mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-12 18:56:11 +08:00
Move java files back into api/ directory.
They were moved out by the cherry-picks.
This commit is contained in:
parent
2e0f40ff51
commit
1dfbebf98e
@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
|
||||||
import org.apache.cordova.api.PluginResult;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
public class CallbackContext {
|
|
||||||
private static final String LOG_TAG = "CordovaPlugin";
|
|
||||||
|
|
||||||
private String callbackId;
|
|
||||||
private CordovaWebView webView;
|
|
||||||
private boolean finished;
|
|
||||||
private int changingThreads;
|
|
||||||
|
|
||||||
public CallbackContext(String callbackId, CordovaWebView webView) {
|
|
||||||
this.callbackId = callbackId;
|
|
||||||
this.webView = webView;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFinished() {
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isChangingThreads() {
|
|
||||||
return changingThreads > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCallbackId() {
|
|
||||||
return callbackId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendPluginResult(PluginResult pluginResult) {
|
|
||||||
synchronized (this) {
|
|
||||||
if (finished) {
|
|
||||||
Log.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
finished = !pluginResult.getKeepCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
webView.sendPluginResult(pluginResult, callbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success(JSONObject message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success(String message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success(JSONArray message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success(byte[] message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success(int message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for success callbacks that just returns the Status.OK by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the success result.
|
|
||||||
*/
|
|
||||||
public void success() {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for error callbacks that just returns the Status.ERROR by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the error result.
|
|
||||||
*/
|
|
||||||
public void error(JSONObject message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for error callbacks that just returns the Status.ERROR by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the error result.
|
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
|
||||||
*/
|
|
||||||
public void error(String message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for error callbacks that just returns the Status.ERROR by default
|
|
||||||
*
|
|
||||||
* @param message The message to add to the error result.
|
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
|
||||||
*/
|
|
||||||
public void error(int message) {
|
|
||||||
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import org.apache.cordova.api.CordovaPlugin;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Activity interface that is implemented by CordovaActivity.
|
|
||||||
* It is used to isolate plugin development, and remove dependency on entire Cordova library.
|
|
||||||
*/
|
|
||||||
public interface CordovaInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
|
||||||
* your onActivityResult() method will be called.
|
|
||||||
*
|
|
||||||
* @param command The command object
|
|
||||||
* @param intent The intent to start
|
|
||||||
* @param requestCode The request code that is passed to callback to identify the activity
|
|
||||||
*/
|
|
||||||
abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the plugin to be called when a sub-activity exits.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin on which onActivityResult is to be called
|
|
||||||
*/
|
|
||||||
abstract public void setActivityResultCallback(CordovaPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Android activity.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public abstract Activity getActivity();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a message is sent to plugin.
|
|
||||||
*
|
|
||||||
* @param id The message id
|
|
||||||
* @param data The message data
|
|
||||||
* @return Object or null
|
|
||||||
*/
|
|
||||||
public Object onMessage(String id, Object data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a shared thread pool that can be used for background tasks.
|
|
||||||
*/
|
|
||||||
public ExecutorService getThreadPool();
|
|
||||||
}
|
|
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import org.apache.cordova.CordovaArgs;
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
|
||||||
import org.apache.cordova.api.CallbackContext;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugins must extend this class and override one of the execute methods.
|
|
||||||
*/
|
|
||||||
public class CordovaPlugin {
|
|
||||||
public String id;
|
|
||||||
public CordovaWebView webView; // WebView object
|
|
||||||
public CordovaInterface cordova;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param cordova The context of the main Activity.
|
|
||||||
* @param webView The associated CordovaWebView.
|
|
||||||
*/
|
|
||||||
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
|
||||||
assert this.cordova == null;
|
|
||||||
this.cordova = cordova;
|
|
||||||
this.webView = webView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 rawArgs The exec() arguments in JSON form.
|
|
||||||
* @param callbackContext The callback context used when calling back into JavaScript.
|
|
||||||
* @return Whether the action was valid.
|
|
||||||
*/
|
|
||||||
public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
|
|
||||||
JSONArray args = new JSONArray(rawArgs);
|
|
||||||
return execute(action, args, 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.
|
|
||||||
* @param callbackContext The callback context used when calling back into JavaScript.
|
|
||||||
* @return Whether the action was valid.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the system is about to start resuming a previous activity.
|
|
||||||
*
|
|
||||||
* @param multitasking Flag indicating if multitasking is turned on for app
|
|
||||||
*/
|
|
||||||
public void onPause(boolean multitasking) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity will start interacting with the user.
|
|
||||||
*
|
|
||||||
* @param multitasking Flag indicating if multitasking is turned on for app
|
|
||||||
*/
|
|
||||||
public void onResume(boolean multitasking) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity receives a new intent.
|
|
||||||
*/
|
|
||||||
public void onNewIntent(Intent intent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The final call you receive before your activity is destroyed.
|
|
||||||
*/
|
|
||||||
public void onDestroy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a message is sent to plugin.
|
|
||||||
*
|
|
||||||
* @param id The message id
|
|
||||||
* @param data The message data
|
|
||||||
* @return Object to stop propagation or null
|
|
||||||
*/
|
|
||||||
public Object onMessage(String id, Object data) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when an activity you launched exits, giving you the requestCode you started it with,
|
|
||||||
* the resultCode it returned, and any additional data from it.
|
|
||||||
*
|
|
||||||
* @param requestCode The request code originally supplied to startActivityForResult(),
|
|
||||||
* allowing you to identify who this result came from.
|
|
||||||
* @param resultCode The integer result code returned by the child activity through its setResult().
|
|
||||||
* @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
|
||||||
*/
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By specifying a <url-filter> in config.xml you can map a URL (using startsWith atm) to this method.
|
|
||||||
*
|
|
||||||
* @param url The URL that is trying to be loaded in the Cordova webview.
|
|
||||||
* @return Return true to prevent the URL from loading. Default is false.
|
|
||||||
*/
|
|
||||||
public boolean onOverrideUrlLoading(String url) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for redirecting requests. Applies to WebView requests as well as requests made by plugins.
|
|
||||||
*/
|
|
||||||
public Uri remapUri(Uri uri) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the WebView does a top-level navigation or refreshes.
|
|
||||||
*
|
|
||||||
* Plugins should stop any long-running processes and clean up internal state.
|
|
||||||
*
|
|
||||||
* Does nothing by default.
|
|
||||||
*/
|
|
||||||
public void onReset() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,6 +29,7 @@ import android.util.Base64;
|
|||||||
|
|
||||||
import com.squareup.okhttp.OkHttpClient;
|
import com.squareup.okhttp.OkHttpClient;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.PluginManager;
|
||||||
import org.apache.http.util.EncodingUtils;
|
import org.apache.http.util.EncodingUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -49,6 +49,7 @@ import javax.net.ssl.X509TrustManager;
|
|||||||
|
|
||||||
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
|
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
|
||||||
import org.apache.cordova.api.CallbackContext;
|
import org.apache.cordova.api.CallbackContext;
|
||||||
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -1,234 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log to Android logging system.
|
|
||||||
*
|
|
||||||
* Log message can be a string or a printf formatted string with arguments.
|
|
||||||
* See http://developer.android.com/reference/java/util/Formatter.html
|
|
||||||
*/
|
|
||||||
public class LOG {
|
|
||||||
|
|
||||||
public static final int VERBOSE = Log.VERBOSE;
|
|
||||||
public static final int DEBUG = Log.DEBUG;
|
|
||||||
public static final int INFO = Log.INFO;
|
|
||||||
public static final int WARN = Log.WARN;
|
|
||||||
public static final int ERROR = Log.ERROR;
|
|
||||||
|
|
||||||
// Current log level
|
|
||||||
public static int LOGLEVEL = Log.ERROR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current log level.
|
|
||||||
*
|
|
||||||
* @param logLevel
|
|
||||||
*/
|
|
||||||
public static void setLogLevel(int logLevel) {
|
|
||||||
LOGLEVEL = logLevel;
|
|
||||||
Log.i("CordovaLog", "Changing log level to " + logLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current log level.
|
|
||||||
*
|
|
||||||
* @param logLevel
|
|
||||||
*/
|
|
||||||
public static void setLogLevel(String logLevel) {
|
|
||||||
if ("VERBOSE".equals(logLevel)) LOGLEVEL = VERBOSE;
|
|
||||||
else if ("DEBUG".equals(logLevel)) LOGLEVEL = DEBUG;
|
|
||||||
else if ("INFO".equals(logLevel)) LOGLEVEL = INFO;
|
|
||||||
else if ("WARN".equals(logLevel)) LOGLEVEL = WARN;
|
|
||||||
else if ("ERROR".equals(logLevel)) LOGLEVEL = ERROR;
|
|
||||||
Log.i("CordovaLog", "Changing log level to " + logLevel + "(" + LOGLEVEL + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if log level will be logged
|
|
||||||
*
|
|
||||||
* @param logLevel
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean isLoggable(int logLevel) {
|
|
||||||
return (logLevel >= LOGLEVEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verbose log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public static void v(String tag, String s) {
|
|
||||||
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public static void d(String tag, String s) {
|
|
||||||
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Info log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public static void i(String tag, String s) {
|
|
||||||
if (LOG.INFO >= LOGLEVEL) Log.i(tag, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Warning log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public static void w(String tag, String s) {
|
|
||||||
if (LOG.WARN >= LOGLEVEL) Log.w(tag, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
*/
|
|
||||||
public static void e(String tag, String s) {
|
|
||||||
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verbose log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void v(String tag, String s, Throwable e) {
|
|
||||||
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void d(String tag, String s, Throwable e) {
|
|
||||||
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Info log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void i(String tag, String s, Throwable e) {
|
|
||||||
if (LOG.INFO >= LOGLEVEL) Log.i(tag, s, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Warning log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void w(String tag, String s, Throwable e) {
|
|
||||||
if (LOG.WARN >= LOGLEVEL) Log.w(tag, s, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error log message.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void e(String tag, String s, Throwable e) {
|
|
||||||
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verbose log message with printf formatting.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void v(String tag, String s, Object... args) {
|
|
||||||
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, String.format(s, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug log message with printf formatting.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void d(String tag, String s, Object... args) {
|
|
||||||
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, String.format(s, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Info log message with printf formatting.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void i(String tag, String s, Object... args) {
|
|
||||||
if (LOG.INFO >= LOGLEVEL) Log.i(tag, String.format(s, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Warning log message with printf formatting.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void w(String tag, String s, Object... args) {
|
|
||||||
if (LOG.WARN >= LOGLEVEL) Log.w(tag, String.format(s, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error log message with printf formatting.
|
|
||||||
*
|
|
||||||
* @param tag
|
|
||||||
* @param s
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void e(String tag, String s, Object... args) {
|
|
||||||
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, String.format(s, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
|
||||||
import org.apache.cordova.api.CordovaPlugin;
|
|
||||||
|
|
||||||
//import android.content.Context;
|
|
||||||
//import android.webkit.WebView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a service entry object.
|
|
||||||
*/
|
|
||||||
public class PluginEntry {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the service that this plugin implements
|
|
||||||
*/
|
|
||||||
public String service = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The plugin class name that implements the service.
|
|
||||||
*/
|
|
||||||
public String pluginClass = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The plugin object.
|
|
||||||
* Plugin objects are only created when they are called from JavaScript. (see PluginManager.exec)
|
|
||||||
* The exception is if the onload flag is set, then they are created when PluginManager is initialized.
|
|
||||||
*/
|
|
||||||
public CordovaPlugin plugin = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag that indicates the plugin object should be created when PluginManager is initialized.
|
|
||||||
*/
|
|
||||||
public boolean onload = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param service The name of the service
|
|
||||||
* @param pluginClass The plugin class name
|
|
||||||
* @param onload Create plugin object when HTML page is loaded
|
|
||||||
*/
|
|
||||||
public PluginEntry(String service, String pluginClass, boolean onload) {
|
|
||||||
this.service = service;
|
|
||||||
this.pluginClass = pluginClass;
|
|
||||||
this.onload = onload;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alternate constructor
|
|
||||||
*
|
|
||||||
* @param service The name of the service
|
|
||||||
* @param plugin The plugin associated with this entry
|
|
||||||
*/
|
|
||||||
public PluginEntry(String service, CordovaPlugin plugin) {
|
|
||||||
this.service = service;
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.pluginClass = plugin.getClass().getName();
|
|
||||||
this.onload = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create plugin object.
|
|
||||||
* If plugin is already created, then just return it.
|
|
||||||
*
|
|
||||||
* @return The plugin object
|
|
||||||
*/
|
|
||||||
public CordovaPlugin createPlugin(CordovaWebView webView, CordovaInterface ctx) {
|
|
||||||
if (this.plugin != null) {
|
|
||||||
return this.plugin;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class c = getClassByName(this.pluginClass);
|
|
||||||
if (isCordovaPlugin(c)) {
|
|
||||||
this.plugin = (CordovaPlugin) c.newInstance();
|
|
||||||
this.plugin.initialize(ctx, webView);
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println("Error adding plugin " + this.pluginClass + ".");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the class.
|
|
||||||
*
|
|
||||||
* @param clazz
|
|
||||||
* @return
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private Class getClassByName(final String clazz) throws ClassNotFoundException {
|
|
||||||
Class c = null;
|
|
||||||
if (clazz != null) {
|
|
||||||
c = Class.forName(clazz);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the given class extends CordovaPlugin.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private boolean isCordovaPlugin(Class c) {
|
|
||||||
if (c != null) {
|
|
||||||
return org.apache.cordova.api.CordovaPlugin.class.isAssignableFrom(c);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,436 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import org.apache.cordova.CordovaArgs;
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
|
||||||
import org.apache.cordova.api.CallbackContext;
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
|
||||||
import org.apache.cordova.api.CordovaPlugin;
|
|
||||||
import org.apache.cordova.api.PluginEntry;
|
|
||||||
import org.apache.cordova.api.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.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PluginManager is exposed to JavaScript in the Cordova WebView.
|
|
||||||
*
|
|
||||||
* Calling native plugin code can be done by calling PluginManager.exec(...)
|
|
||||||
* from JavaScript.
|
|
||||||
*/
|
|
||||||
public class PluginManager {
|
|
||||||
private static String TAG = "PluginManager";
|
|
||||||
|
|
||||||
// List of service entries
|
|
||||||
private final HashMap<String, PluginEntry> entries = new HashMap<String, PluginEntry>();
|
|
||||||
|
|
||||||
private final CordovaInterface ctx;
|
|
||||||
private final CordovaWebView app;
|
|
||||||
|
|
||||||
// Flag to track first time through
|
|
||||||
private boolean firstRun;
|
|
||||||
|
|
||||||
// Map URL schemes like foo: to plugins that want to handle those schemes
|
|
||||||
// This would allow how all URLs are handled to be offloaded to a plugin
|
|
||||||
protected HashMap<String, String> urlMap = new HashMap<String, String>();
|
|
||||||
|
|
||||||
private AtomicInteger numPendingUiExecs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param app
|
|
||||||
* @param ctx
|
|
||||||
*/
|
|
||||||
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.app = app;
|
|
||||||
this.firstRun = true;
|
|
||||||
this.numPendingUiExecs = new AtomicInteger(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init when loading a new HTML page into webview.
|
|
||||||
*/
|
|
||||||
public void init() {
|
|
||||||
LOG.d(TAG, "init()");
|
|
||||||
|
|
||||||
// If first time, then load plugins from config.xml file
|
|
||||||
if (this.firstRun) {
|
|
||||||
this.loadPlugins();
|
|
||||||
this.firstRun = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop plugins on current HTML page and discard plugin objects
|
|
||||||
else {
|
|
||||||
this.onPause(false);
|
|
||||||
this.onDestroy();
|
|
||||||
this.clearPluginObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert PluginManager service
|
|
||||||
this.addService(new PluginEntry("PluginManager", new PluginManagerService()));
|
|
||||||
|
|
||||||
// Start up all plugins that have onload specified
|
|
||||||
this.startupPlugins();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load plugins from res/xml/config.xml
|
|
||||||
*/
|
|
||||||
public void loadPlugins() {
|
|
||||||
int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getClass().getPackage().getName());
|
|
||||||
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();
|
|
||||||
//This is for the old scheme
|
|
||||||
if (strNode.equals("plugin")) {
|
|
||||||
service = xml.getAttributeValue(null, "name");
|
|
||||||
pluginClass = xml.getAttributeValue(null, "value");
|
|
||||||
Log.d(TAG, "<plugin> tags are deprecated, please use <features> instead. <plugin> will no longer work as of Cordova 3.0");
|
|
||||||
onload = "true".equals(xml.getAttributeValue(null, "onload"));
|
|
||||||
}
|
|
||||||
//What is this?
|
|
||||||
else if (strNode.equals("url-filter")) {
|
|
||||||
this.urlMap.put(xml.getAttributeValue(null, "value"), service);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
eventType = xml.next();
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all plugin objects.
|
|
||||||
*/
|
|
||||||
public void clearPluginObjects() {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
entry.plugin = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create plugins objects that have onload set.
|
|
||||||
*/
|
|
||||||
public void startupPlugins() {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.onload) {
|
|
||||||
entry.createPlugin(this.app, this.ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives a request for execution and fulfills it by finding the appropriate
|
|
||||||
* Java class and calling it's execute method.
|
|
||||||
*
|
|
||||||
* PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
|
|
||||||
* string is returned that will indicate if any errors have occurred when trying to find
|
|
||||||
* or execute the class denoted by the clazz argument.
|
|
||||||
*
|
|
||||||
* @param service String containing the service to run
|
|
||||||
* @param action String containing the action that the class is supposed to perform. This is
|
|
||||||
* passed to the plugin execute method and it is up to the plugin developer
|
|
||||||
* how to deal with it.
|
|
||||||
* @param callbackId String containing the id of the callback that is execute in JavaScript if
|
|
||||||
* this is an async plugin call.
|
|
||||||
* @param rawArgs An Array literal string containing any arguments needed in the
|
|
||||||
* plugin execute method.
|
|
||||||
*/
|
|
||||||
public void exec(final String service, final String action, final String callbackId, final String rawArgs) {
|
|
||||||
if (numPendingUiExecs.get() > 0) {
|
|
||||||
numPendingUiExecs.getAndIncrement();
|
|
||||||
this.ctx.getActivity().runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
execHelper(service, action, callbackId, rawArgs);
|
|
||||||
numPendingUiExecs.getAndDecrement();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
execHelper(service, action, callbackId, rawArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void execHelper(final String service, final String action, final String callbackId, final String rawArgs) {
|
|
||||||
CordovaPlugin plugin = getPlugin(service);
|
|
||||||
if (plugin == null) {
|
|
||||||
Log.d(TAG, "exec() call to unknown plugin: " + service);
|
|
||||||
PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
|
|
||||||
app.sendPluginResult(cr, callbackId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
CallbackContext callbackContext = new CallbackContext(callbackId, app);
|
|
||||||
boolean wasValidAction = plugin.execute(action, rawArgs, callbackContext);
|
|
||||||
if (!wasValidAction) {
|
|
||||||
PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION);
|
|
||||||
app.sendPluginResult(cr, callbackId);
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
|
||||||
app.sendPluginResult(cr, callbackId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void exec(String service, String action, String callbackId, String jsonArgs, boolean async) {
|
|
||||||
exec(service, action, callbackId, jsonArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the plugin object that implements the service.
|
|
||||||
* If the plugin object does not already exist, then create it.
|
|
||||||
* If the service doesn't exist, then return null.
|
|
||||||
*
|
|
||||||
* @param service The name of the service.
|
|
||||||
* @return CordovaPlugin or null
|
|
||||||
*/
|
|
||||||
public CordovaPlugin getPlugin(String service) {
|
|
||||||
PluginEntry entry = this.entries.get(service);
|
|
||||||
if (entry == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CordovaPlugin plugin = entry.plugin;
|
|
||||||
if (plugin == null) {
|
|
||||||
plugin = entry.createPlugin(this.app, this.ctx);
|
|
||||||
}
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a plugin class that implements a service to the service entry table.
|
|
||||||
* This does not create the plugin object instance.
|
|
||||||
*
|
|
||||||
* @param service The service name
|
|
||||||
* @param className The plugin class name
|
|
||||||
*/
|
|
||||||
public void addService(String service, String className) {
|
|
||||||
PluginEntry entry = new PluginEntry(service, className, false);
|
|
||||||
this.addService(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a plugin class that implements a service to the service entry table.
|
|
||||||
* This does not create the plugin object instance.
|
|
||||||
*
|
|
||||||
* @param entry The plugin entry
|
|
||||||
*/
|
|
||||||
public void addService(PluginEntry entry) {
|
|
||||||
this.entries.put(entry.service, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the system is about to start resuming a previous activity.
|
|
||||||
*
|
|
||||||
* @param multitasking Flag indicating if multitasking is turned on for app
|
|
||||||
*/
|
|
||||||
public void onPause(boolean multitasking) {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
entry.plugin.onPause(multitasking);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity will start interacting with the user.
|
|
||||||
*
|
|
||||||
* @param multitasking Flag indicating if multitasking is turned on for app
|
|
||||||
*/
|
|
||||||
public void onResume(boolean multitasking) {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
entry.plugin.onResume(multitasking);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The final call you receive before your activity is destroyed.
|
|
||||||
*/
|
|
||||||
public void onDestroy() {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
entry.plugin.onDestroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message to all plugins.
|
|
||||||
*
|
|
||||||
* @param id The message id
|
|
||||||
* @param data The message data
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Object postMessage(String id, Object data) {
|
|
||||||
Object obj = this.ctx.onMessage(id, data);
|
|
||||||
if (obj != null) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
obj = entry.plugin.onMessage(id, data);
|
|
||||||
if (obj != null) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity receives a new intent.
|
|
||||||
*/
|
|
||||||
public void onNewIntent(Intent intent) {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
entry.plugin.onNewIntent(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the URL of the webview changes.
|
|
||||||
*
|
|
||||||
* @param url The URL that is being changed to.
|
|
||||||
* @return Return false to allow the URL to load, return true to prevent the URL from loading.
|
|
||||||
*/
|
|
||||||
public boolean onOverrideUrlLoading(String url) {
|
|
||||||
Iterator<Entry<String, String>> it = this.urlMap.entrySet().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
HashMap.Entry<String, String> pairs = it.next();
|
|
||||||
if (url.startsWith(pairs.getKey())) {
|
|
||||||
return this.getPlugin(pairs.getValue()).onOverrideUrlLoading(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the app navigates or refreshes.
|
|
||||||
*/
|
|
||||||
public void onReset() {
|
|
||||||
Iterator<PluginEntry> it = this.entries.values().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
CordovaPlugin plugin = it.next().plugin;
|
|
||||||
if (plugin != null) {
|
|
||||||
plugin.onReset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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=incubator-cordova-android.git;a=blob;f=framework/res/xml/plugins.xml");
|
|
||||||
LOG.e(TAG, "=====================================================================================");
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri remapUri(Uri uri) {
|
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
|
||||||
if (entry.plugin != null) {
|
|
||||||
Uri ret = entry.plugin.remapUri(uri);
|
|
||||||
if (ret != null) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PluginManagerService extends CordovaPlugin {
|
|
||||||
@Override
|
|
||||||
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
|
||||||
if ("startup".equals(action)) {
|
|
||||||
// The onPageStarted event of CordovaWebViewClient resets the queue of messages to be returned to javascript in response
|
|
||||||
// to exec calls. Since this event occurs on the UI thread and exec calls happen on the WebCore thread it is possible
|
|
||||||
// that onPageStarted occurs after exec calls have started happening on a new page, which can cause the message queue
|
|
||||||
// to be reset between the queuing of a new message and its retrieval by javascript. To avoid this from happening,
|
|
||||||
// javascript always sends a "startup" exec upon loading a new page which causes all future exec calls to happen on the UI
|
|
||||||
// thread (and hence after onPageStarted) until there are no more pending exec calls remaining.
|
|
||||||
numPendingUiExecs.getAndIncrement();
|
|
||||||
ctx.getActivity().runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
numPendingUiExecs.getAndDecrement();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import android.util.Base64;
|
|
||||||
|
|
||||||
public class PluginResult {
|
|
||||||
private final int status;
|
|
||||||
private final int messageType;
|
|
||||||
private boolean keepCallback = false;
|
|
||||||
private String strMessage;
|
|
||||||
private String encodedMessage;
|
|
||||||
|
|
||||||
public PluginResult(Status status) {
|
|
||||||
this(status, PluginResult.StatusMessages[status.ordinal()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, String message) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = message == null ? MESSAGE_TYPE_NULL : MESSAGE_TYPE_STRING;
|
|
||||||
this.strMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, JSONArray message) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = MESSAGE_TYPE_JSON;
|
|
||||||
encodedMessage = message.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, JSONObject message) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = MESSAGE_TYPE_JSON;
|
|
||||||
encodedMessage = message.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, int i) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = MESSAGE_TYPE_NUMBER;
|
|
||||||
this.encodedMessage = ""+i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, float f) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = MESSAGE_TYPE_NUMBER;
|
|
||||||
this.encodedMessage = ""+f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, boolean b) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = MESSAGE_TYPE_BOOLEAN;
|
|
||||||
this.encodedMessage = Boolean.toString(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, byte[] data) {
|
|
||||||
this(status, data, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginResult(Status status, byte[] data, boolean binaryString) {
|
|
||||||
this.status = status.ordinal();
|
|
||||||
this.messageType = binaryString ? MESSAGE_TYPE_BINARYSTRING : MESSAGE_TYPE_ARRAYBUFFER;
|
|
||||||
this.encodedMessage = Base64.encodeToString(data, Base64.NO_WRAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeepCallback(boolean b) {
|
|
||||||
this.keepCallback = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMessageType() {
|
|
||||||
return messageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
if (encodedMessage == null) {
|
|
||||||
encodedMessage = JSONObject.quote(strMessage);
|
|
||||||
}
|
|
||||||
return encodedMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If messageType == MESSAGE_TYPE_STRING, then returns the message string.
|
|
||||||
* Otherwise, returns null.
|
|
||||||
*/
|
|
||||||
public String getStrMessage() {
|
|
||||||
return strMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getKeepCallback() {
|
|
||||||
return this.keepCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
|
||||||
public String getJSONString() {
|
|
||||||
return "{\"status\":" + this.status + ",\"message\":" + this.getMessage() + ",\"keepCallback\":" + this.keepCallback + "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
|
||||||
public String toCallbackString(String callbackId) {
|
|
||||||
// If no result to be sent and keeping callback, then no need to sent back to JavaScript
|
|
||||||
if ((status == PluginResult.Status.NO_RESULT.ordinal()) && keepCallback) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
|
|
||||||
if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
|
|
||||||
return toSuccessCallbackString(callbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toErrorCallbackString(callbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
|
||||||
public String toSuccessCallbackString(String callbackId) {
|
|
||||||
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
|
||||||
public String toErrorCallbackString(String callbackId) {
|
|
||||||
return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int MESSAGE_TYPE_STRING = 1;
|
|
||||||
public static final int MESSAGE_TYPE_JSON = 2;
|
|
||||||
public static final int MESSAGE_TYPE_NUMBER = 3;
|
|
||||||
public static final int MESSAGE_TYPE_BOOLEAN = 4;
|
|
||||||
public static final int MESSAGE_TYPE_NULL = 5;
|
|
||||||
public static final int MESSAGE_TYPE_ARRAYBUFFER = 6;
|
|
||||||
// Use BINARYSTRING when your string may contain null characters.
|
|
||||||
// This is required to work around a bug in the platform :(.
|
|
||||||
public static final int MESSAGE_TYPE_BINARYSTRING = 7;
|
|
||||||
|
|
||||||
public static String[] StatusMessages = new String[] {
|
|
||||||
"No result",
|
|
||||||
"OK",
|
|
||||||
"Class not found",
|
|
||||||
"Illegal access",
|
|
||||||
"Instantiation error",
|
|
||||||
"Malformed url",
|
|
||||||
"IO error",
|
|
||||||
"Invalid action",
|
|
||||||
"JSON error",
|
|
||||||
"Error"
|
|
||||||
};
|
|
||||||
|
|
||||||
public enum Status {
|
|
||||||
NO_RESULT,
|
|
||||||
OK,
|
|
||||||
CLASS_NOT_FOUND_EXCEPTION,
|
|
||||||
ILLEGAL_ACCESS_EXCEPTION,
|
|
||||||
INSTANTIATION_EXCEPTION,
|
|
||||||
MALFORMED_URL_EXCEPTION,
|
|
||||||
IO_EXCEPTION,
|
|
||||||
INVALID_ACTION,
|
|
||||||
JSON_EXCEPTION,
|
|
||||||
ERROR
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,10 +18,131 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.api.PluginResult;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class CallbackContext {
|
||||||
|
private static final String LOG_TAG = "CordovaPlugin";
|
||||||
|
|
||||||
|
private String callbackId;
|
||||||
|
private CordovaWebView webView;
|
||||||
|
private boolean finished;
|
||||||
|
private int changingThreads;
|
||||||
|
|
||||||
public class CallbackContext extends org.apache.cordova.CallbackContext {
|
|
||||||
public CallbackContext(String callbackId, CordovaWebView webView) {
|
public CallbackContext(String callbackId, CordovaWebView webView) {
|
||||||
super(callbackId, webView);
|
this.callbackId = callbackId;
|
||||||
|
this.webView = webView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChangingThreads() {
|
||||||
|
return changingThreads > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallbackId() {
|
||||||
|
return callbackId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendPluginResult(PluginResult pluginResult) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (finished) {
|
||||||
|
Log.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
finished = !pluginResult.getKeepCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webView.sendPluginResult(pluginResult, callbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success(JSONObject message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success(String message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success(JSONArray message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success(byte[] message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success(int message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the success result.
|
||||||
|
*/
|
||||||
|
public void success() {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.OK));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for error callbacks that just returns the Status.ERROR by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the error result.
|
||||||
|
*/
|
||||||
|
public void error(JSONObject message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for error callbacks that just returns the Status.ERROR by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the error result.
|
||||||
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
|
*/
|
||||||
|
public void error(String message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for error callbacks that just returns the Status.ERROR by default
|
||||||
|
*
|
||||||
|
* @param message The message to add to the error result.
|
||||||
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
|
*/
|
||||||
|
public void error(int message) {
|
||||||
|
sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,55 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Activity interface that is implemented by CordovaActivity.
|
* The Activity interface that is implemented by CordovaActivity.
|
||||||
* It is used to isolate plugin development, and remove dependency on entire Cordova library.
|
* It is used to isolate plugin development, and remove dependency on entire Cordova library.
|
||||||
*/
|
*/
|
||||||
public interface CordovaInterface extends org.apache.cordova.CordovaInterface {
|
public interface CordovaInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
||||||
|
* your onActivityResult() method will be called.
|
||||||
|
*
|
||||||
|
* @param command The command object
|
||||||
|
* @param intent The intent to start
|
||||||
|
* @param requestCode The request code that is passed to callback to identify the activity
|
||||||
|
*/
|
||||||
|
abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the plugin to be called when a sub-activity exits.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin on which onActivityResult is to be called
|
||||||
|
*/
|
||||||
|
abstract public void setActivityResultCallback(CordovaPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Android activity.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract Activity getActivity();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a message is sent to plugin.
|
||||||
|
*
|
||||||
|
* @param id The message id
|
||||||
|
* @param data The message data
|
||||||
|
* @return Object or null
|
||||||
|
*/
|
||||||
|
public Object onMessage(String id, Object data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a shared thread pool that can be used for background tasks.
|
||||||
|
*/
|
||||||
|
public ExecutorService getThreadPool();
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,165 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
public class CordovaPlugin extends org.apache.cordova.CordovaPlugin {
|
import org.apache.cordova.CordovaArgs;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.CallbackContext;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugins must extend this class and override one of the execute methods.
|
||||||
|
*/
|
||||||
|
public class CordovaPlugin {
|
||||||
|
public String id;
|
||||||
|
public CordovaWebView webView; // WebView object
|
||||||
|
public CordovaInterface cordova;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cordova The context of the main Activity.
|
||||||
|
* @param webView The associated CordovaWebView.
|
||||||
|
*/
|
||||||
|
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
||||||
|
assert this.cordova == null;
|
||||||
|
this.cordova = cordova;
|
||||||
|
this.webView = webView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 rawArgs The exec() arguments in JSON form.
|
||||||
|
* @param callbackContext The callback context used when calling back into JavaScript.
|
||||||
|
* @return Whether the action was valid.
|
||||||
|
*/
|
||||||
|
public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
|
||||||
|
JSONArray args = new JSONArray(rawArgs);
|
||||||
|
return execute(action, args, 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.
|
||||||
|
* @param callbackContext The callback context used when calling back into JavaScript.
|
||||||
|
* @return Whether the action was valid.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the system is about to start resuming a previous activity.
|
||||||
|
*
|
||||||
|
* @param multitasking Flag indicating if multitasking is turned on for app
|
||||||
|
*/
|
||||||
|
public void onPause(boolean multitasking) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity will start interacting with the user.
|
||||||
|
*
|
||||||
|
* @param multitasking Flag indicating if multitasking is turned on for app
|
||||||
|
*/
|
||||||
|
public void onResume(boolean multitasking) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity receives a new intent.
|
||||||
|
*/
|
||||||
|
public void onNewIntent(Intent intent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The final call you receive before your activity is destroyed.
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a message is sent to plugin.
|
||||||
|
*
|
||||||
|
* @param id The message id
|
||||||
|
* @param data The message data
|
||||||
|
* @return Object to stop propagation or null
|
||||||
|
*/
|
||||||
|
public Object onMessage(String id, Object data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an activity you launched exits, giving you the requestCode you started it with,
|
||||||
|
* the resultCode it returned, and any additional data from it.
|
||||||
|
*
|
||||||
|
* @param requestCode The request code originally supplied to startActivityForResult(),
|
||||||
|
* allowing you to identify who this result came from.
|
||||||
|
* @param resultCode The integer result code returned by the child activity through its setResult().
|
||||||
|
* @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
||||||
|
*/
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By specifying a <url-filter> in config.xml you can map a URL (using startsWith atm) to this method.
|
||||||
|
*
|
||||||
|
* @param url The URL that is trying to be loaded in the Cordova webview.
|
||||||
|
* @return Return true to prevent the URL from loading. Default is false.
|
||||||
|
*/
|
||||||
|
public boolean onOverrideUrlLoading(String url) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for redirecting requests. Applies to WebView requests as well as requests made by plugins.
|
||||||
|
*/
|
||||||
|
public Uri remapUri(Uri uri) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the WebView does a top-level navigation or refreshes.
|
||||||
|
*
|
||||||
|
* Plugins should stop any long-running processes and clean up internal state.
|
||||||
|
*
|
||||||
|
* Does nothing by default.
|
||||||
|
*/
|
||||||
|
public void onReset() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,217 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
public class LOG extends org.apache.cordova.LOG {
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log to Android logging system.
|
||||||
|
*
|
||||||
|
* Log message can be a string or a printf formatted string with arguments.
|
||||||
|
* See http://developer.android.com/reference/java/util/Formatter.html
|
||||||
|
*/
|
||||||
|
public class LOG {
|
||||||
|
|
||||||
|
public static final int VERBOSE = Log.VERBOSE;
|
||||||
|
public static final int DEBUG = Log.DEBUG;
|
||||||
|
public static final int INFO = Log.INFO;
|
||||||
|
public static final int WARN = Log.WARN;
|
||||||
|
public static final int ERROR = Log.ERROR;
|
||||||
|
|
||||||
|
// Current log level
|
||||||
|
public static int LOGLEVEL = Log.ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current log level.
|
||||||
|
*
|
||||||
|
* @param logLevel
|
||||||
|
*/
|
||||||
|
public static void setLogLevel(int logLevel) {
|
||||||
|
LOGLEVEL = logLevel;
|
||||||
|
Log.i("CordovaLog", "Changing log level to " + logLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current log level.
|
||||||
|
*
|
||||||
|
* @param logLevel
|
||||||
|
*/
|
||||||
|
public static void setLogLevel(String logLevel) {
|
||||||
|
if ("VERBOSE".equals(logLevel)) LOGLEVEL = VERBOSE;
|
||||||
|
else if ("DEBUG".equals(logLevel)) LOGLEVEL = DEBUG;
|
||||||
|
else if ("INFO".equals(logLevel)) LOGLEVEL = INFO;
|
||||||
|
else if ("WARN".equals(logLevel)) LOGLEVEL = WARN;
|
||||||
|
else if ("ERROR".equals(logLevel)) LOGLEVEL = ERROR;
|
||||||
|
Log.i("CordovaLog", "Changing log level to " + logLevel + "(" + LOGLEVEL + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if log level will be logged
|
||||||
|
*
|
||||||
|
* @param logLevel
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isLoggable(int logLevel) {
|
||||||
|
return (logLevel >= LOGLEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void v(String tag, String s) {
|
||||||
|
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void d(String tag, String s) {
|
||||||
|
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Info log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void i(String tag, String s) {
|
||||||
|
if (LOG.INFO >= LOGLEVEL) Log.i(tag, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void w(String tag, String s) {
|
||||||
|
if (LOG.WARN >= LOGLEVEL) Log.w(tag, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public static void e(String tag, String s) {
|
||||||
|
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static void v(String tag, String s, Throwable e) {
|
||||||
|
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static void d(String tag, String s, Throwable e) {
|
||||||
|
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Info log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static void i(String tag, String s, Throwable e) {
|
||||||
|
if (LOG.INFO >= LOGLEVEL) Log.i(tag, s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static void w(String tag, String s, Throwable e) {
|
||||||
|
if (LOG.WARN >= LOGLEVEL) Log.w(tag, s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error log message.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static void e(String tag, String s, Throwable e) {
|
||||||
|
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose log message with printf formatting.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void v(String tag, String s, Object... args) {
|
||||||
|
if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, String.format(s, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug log message with printf formatting.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void d(String tag, String s, Object... args) {
|
||||||
|
if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, String.format(s, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Info log message with printf formatting.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void i(String tag, String s, Object... args) {
|
||||||
|
if (LOG.INFO >= LOGLEVEL) Log.i(tag, String.format(s, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warning log message with printf formatting.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void w(String tag, String s, Object... args) {
|
||||||
|
if (LOG.WARN >= LOGLEVEL) Log.w(tag, String.format(s, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error log message with printf formatting.
|
||||||
|
*
|
||||||
|
* @param tag
|
||||||
|
* @param s
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void e(String tag, String s, Object... args) {
|
||||||
|
if (LOG.ERROR >= LOGLEVEL) Log.e(tag, String.format(s, args));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,115 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
public class PluginEntry extends org.apache.cordova.PluginEntry {
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
|
|
||||||
|
//import android.content.Context;
|
||||||
|
//import android.webkit.WebView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a service entry object.
|
||||||
|
*/
|
||||||
|
public class PluginEntry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the service that this plugin implements
|
||||||
|
*/
|
||||||
|
public String service = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin class name that implements the service.
|
||||||
|
*/
|
||||||
|
public String pluginClass = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin object.
|
||||||
|
* Plugin objects are only created when they are called from JavaScript. (see PluginManager.exec)
|
||||||
|
* The exception is if the onload flag is set, then they are created when PluginManager is initialized.
|
||||||
|
*/
|
||||||
|
public CordovaPlugin plugin = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag that indicates the plugin object should be created when PluginManager is initialized.
|
||||||
|
*/
|
||||||
|
public boolean onload = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param service The name of the service
|
||||||
|
* @param pluginClass The plugin class name
|
||||||
|
* @param onload Create plugin object when HTML page is loaded
|
||||||
|
*/
|
||||||
public PluginEntry(String service, String pluginClass, boolean onload) {
|
public PluginEntry(String service, String pluginClass, boolean onload) {
|
||||||
super(service, pluginClass, onload);
|
this.service = service;
|
||||||
|
this.pluginClass = pluginClass;
|
||||||
|
this.onload = onload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternate constructor
|
||||||
|
*
|
||||||
|
* @param service The name of the service
|
||||||
|
* @param plugin The plugin associated with this entry
|
||||||
|
*/
|
||||||
public PluginEntry(String service, CordovaPlugin plugin) {
|
public PluginEntry(String service, CordovaPlugin plugin) {
|
||||||
super(service, plugin);
|
this.service = service;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.pluginClass = plugin.getClass().getName();
|
||||||
|
this.onload = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create plugin object.
|
||||||
|
* If plugin is already created, then just return it.
|
||||||
|
*
|
||||||
|
* @return The plugin object
|
||||||
|
*/
|
||||||
|
public CordovaPlugin createPlugin(CordovaWebView webView, CordovaInterface ctx) {
|
||||||
|
if (this.plugin != null) {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
Class c = getClassByName(this.pluginClass);
|
||||||
|
if (isCordovaPlugin(c)) {
|
||||||
|
this.plugin = (CordovaPlugin) c.newInstance();
|
||||||
|
this.plugin.initialize(ctx, webView);
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("Error adding plugin " + this.pluginClass + ".");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class.
|
||||||
|
*
|
||||||
|
* @param clazz
|
||||||
|
* @return
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private Class getClassByName(final String clazz) throws ClassNotFoundException {
|
||||||
|
Class c = null;
|
||||||
|
if (clazz != null) {
|
||||||
|
c = Class.forName(clazz);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given class extends CordovaPlugin.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private boolean isCordovaPlugin(Class c) {
|
||||||
|
if (c != null) {
|
||||||
|
return org.apache.cordova.api.CordovaPlugin.class.isAssignableFrom(c);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,419 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class PluginManager extends org.apache.cordova.PluginManager {
|
import org.apache.cordova.CordovaArgs;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.api.CallbackContext;
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
|
import org.apache.cordova.api.PluginEntry;
|
||||||
|
import org.apache.cordova.api.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.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PluginManager is exposed to JavaScript in the Cordova WebView.
|
||||||
|
*
|
||||||
|
* Calling native plugin code can be done by calling PluginManager.exec(...)
|
||||||
|
* from JavaScript.
|
||||||
|
*/
|
||||||
|
public class PluginManager {
|
||||||
|
private static String TAG = "PluginManager";
|
||||||
|
|
||||||
|
// List of service entries
|
||||||
|
private final HashMap<String, PluginEntry> entries = new HashMap<String, PluginEntry>();
|
||||||
|
|
||||||
|
private final CordovaInterface ctx;
|
||||||
|
private final CordovaWebView app;
|
||||||
|
|
||||||
|
// Flag to track first time through
|
||||||
|
private boolean firstRun;
|
||||||
|
|
||||||
|
// Map URL schemes like foo: to plugins that want to handle those schemes
|
||||||
|
// This would allow how all URLs are handled to be offloaded to a plugin
|
||||||
|
protected HashMap<String, String> urlMap = new HashMap<String, String>();
|
||||||
|
|
||||||
|
private AtomicInteger numPendingUiExecs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param app
|
||||||
|
* @param ctx
|
||||||
|
*/
|
||||||
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
||||||
super(app, ctx);
|
this.ctx = ctx;
|
||||||
|
this.app = app;
|
||||||
|
this.firstRun = true;
|
||||||
|
this.numPendingUiExecs = new AtomicInteger(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init when loading a new HTML page into webview.
|
||||||
|
*/
|
||||||
|
public void init() {
|
||||||
|
LOG.d(TAG, "init()");
|
||||||
|
|
||||||
|
// If first time, then load plugins from config.xml file
|
||||||
|
if (this.firstRun) {
|
||||||
|
this.loadPlugins();
|
||||||
|
this.firstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop plugins on current HTML page and discard plugin objects
|
||||||
|
else {
|
||||||
|
this.onPause(false);
|
||||||
|
this.onDestroy();
|
||||||
|
this.clearPluginObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert PluginManager service
|
||||||
|
this.addService(new PluginEntry("PluginManager", new PluginManagerService()));
|
||||||
|
|
||||||
|
// Start up all plugins that have onload specified
|
||||||
|
this.startupPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load plugins from res/xml/config.xml
|
||||||
|
*/
|
||||||
|
public void loadPlugins() {
|
||||||
|
int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getClass().getPackage().getName());
|
||||||
|
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();
|
||||||
|
//This is for the old scheme
|
||||||
|
if (strNode.equals("plugin")) {
|
||||||
|
service = xml.getAttributeValue(null, "name");
|
||||||
|
pluginClass = xml.getAttributeValue(null, "value");
|
||||||
|
Log.d(TAG, "<plugin> tags are deprecated, please use <features> instead. <plugin> will no longer work as of Cordova 3.0");
|
||||||
|
onload = "true".equals(xml.getAttributeValue(null, "onload"));
|
||||||
|
}
|
||||||
|
//What is this?
|
||||||
|
else if (strNode.equals("url-filter")) {
|
||||||
|
this.urlMap.put(xml.getAttributeValue(null, "value"), service);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
eventType = xml.next();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all plugin objects.
|
||||||
|
*/
|
||||||
|
public void clearPluginObjects() {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
entry.plugin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create plugins objects that have onload set.
|
||||||
|
*/
|
||||||
|
public void startupPlugins() {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.onload) {
|
||||||
|
entry.createPlugin(this.app, this.ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives a request for execution and fulfills it by finding the appropriate
|
||||||
|
* Java class and calling it's execute method.
|
||||||
|
*
|
||||||
|
* PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
|
||||||
|
* string is returned that will indicate if any errors have occurred when trying to find
|
||||||
|
* or execute the class denoted by the clazz argument.
|
||||||
|
*
|
||||||
|
* @param service String containing the service to run
|
||||||
|
* @param action String containing the action that the class is supposed to perform. This is
|
||||||
|
* passed to the plugin execute method and it is up to the plugin developer
|
||||||
|
* how to deal with it.
|
||||||
|
* @param callbackId String containing the id of the callback that is execute in JavaScript if
|
||||||
|
* this is an async plugin call.
|
||||||
|
* @param rawArgs An Array literal string containing any arguments needed in the
|
||||||
|
* plugin execute method.
|
||||||
|
*/
|
||||||
|
public void exec(final String service, final String action, final String callbackId, final String rawArgs) {
|
||||||
|
if (numPendingUiExecs.get() > 0) {
|
||||||
|
numPendingUiExecs.getAndIncrement();
|
||||||
|
this.ctx.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
execHelper(service, action, callbackId, rawArgs);
|
||||||
|
numPendingUiExecs.getAndDecrement();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
execHelper(service, action, callbackId, rawArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execHelper(final String service, final String action, final String callbackId, final String rawArgs) {
|
||||||
|
CordovaPlugin plugin = getPlugin(service);
|
||||||
|
if (plugin == null) {
|
||||||
|
Log.d(TAG, "exec() call to unknown plugin: " + service);
|
||||||
|
PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
|
||||||
|
app.sendPluginResult(cr, callbackId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CallbackContext callbackContext = new CallbackContext(callbackId, app);
|
||||||
|
boolean wasValidAction = plugin.execute(action, rawArgs, callbackContext);
|
||||||
|
if (!wasValidAction) {
|
||||||
|
PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||||
|
app.sendPluginResult(cr, callbackId);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||||
|
app.sendPluginResult(cr, callbackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void exec(String service, String action, String callbackId, String jsonArgs, boolean async) {
|
||||||
|
exec(service, action, callbackId, jsonArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin object that implements the service.
|
||||||
|
* If the plugin object does not already exist, then create it.
|
||||||
|
* If the service doesn't exist, then return null.
|
||||||
|
*
|
||||||
|
* @param service The name of the service.
|
||||||
|
* @return CordovaPlugin or null
|
||||||
|
*/
|
||||||
|
public CordovaPlugin getPlugin(String service) {
|
||||||
|
PluginEntry entry = this.entries.get(service);
|
||||||
|
if (entry == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
CordovaPlugin plugin = entry.plugin;
|
||||||
|
if (plugin == null) {
|
||||||
|
plugin = entry.createPlugin(this.app, this.ctx);
|
||||||
|
}
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a plugin class that implements a service to the service entry table.
|
||||||
|
* This does not create the plugin object instance.
|
||||||
|
*
|
||||||
|
* @param service The service name
|
||||||
|
* @param className The plugin class name
|
||||||
|
*/
|
||||||
|
public void addService(String service, String className) {
|
||||||
|
PluginEntry entry = new PluginEntry(service, className, false);
|
||||||
|
this.addService(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a plugin class that implements a service to the service entry table.
|
||||||
|
* This does not create the plugin object instance.
|
||||||
|
*
|
||||||
|
* @param entry The plugin entry
|
||||||
|
*/
|
||||||
|
public void addService(PluginEntry entry) {
|
||||||
|
this.entries.put(entry.service, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the system is about to start resuming a previous activity.
|
||||||
|
*
|
||||||
|
* @param multitasking Flag indicating if multitasking is turned on for app
|
||||||
|
*/
|
||||||
|
public void onPause(boolean multitasking) {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
entry.plugin.onPause(multitasking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity will start interacting with the user.
|
||||||
|
*
|
||||||
|
* @param multitasking Flag indicating if multitasking is turned on for app
|
||||||
|
*/
|
||||||
|
public void onResume(boolean multitasking) {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
entry.plugin.onResume(multitasking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The final call you receive before your activity is destroyed.
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
entry.plugin.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to all plugins.
|
||||||
|
*
|
||||||
|
* @param id The message id
|
||||||
|
* @param data The message data
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Object postMessage(String id, Object data) {
|
||||||
|
Object obj = this.ctx.onMessage(id, data);
|
||||||
|
if (obj != null) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
obj = entry.plugin.onMessage(id, data);
|
||||||
|
if (obj != null) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the activity receives a new intent.
|
||||||
|
*/
|
||||||
|
public void onNewIntent(Intent intent) {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
entry.plugin.onNewIntent(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the URL of the webview changes.
|
||||||
|
*
|
||||||
|
* @param url The URL that is being changed to.
|
||||||
|
* @return Return false to allow the URL to load, return true to prevent the URL from loading.
|
||||||
|
*/
|
||||||
|
public boolean onOverrideUrlLoading(String url) {
|
||||||
|
Iterator<Entry<String, String>> it = this.urlMap.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
HashMap.Entry<String, String> pairs = it.next();
|
||||||
|
if (url.startsWith(pairs.getKey())) {
|
||||||
|
return this.getPlugin(pairs.getValue()).onOverrideUrlLoading(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the app navigates or refreshes.
|
||||||
|
*/
|
||||||
|
public void onReset() {
|
||||||
|
Iterator<PluginEntry> it = this.entries.values().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
CordovaPlugin plugin = it.next().plugin;
|
||||||
|
if (plugin != null) {
|
||||||
|
plugin.onReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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=incubator-cordova-android.git;a=blob;f=framework/res/xml/plugins.xml");
|
||||||
|
LOG.e(TAG, "=====================================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri remapUri(Uri uri) {
|
||||||
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
|
if (entry.plugin != null) {
|
||||||
|
Uri ret = entry.plugin.remapUri(uri);
|
||||||
|
if (ret != null) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PluginManagerService extends CordovaPlugin {
|
||||||
|
@Override
|
||||||
|
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||||
|
if ("startup".equals(action)) {
|
||||||
|
// The onPageStarted event of CordovaWebViewClient resets the queue of messages to be returned to javascript in response
|
||||||
|
// to exec calls. Since this event occurs on the UI thread and exec calls happen on the WebCore thread it is possible
|
||||||
|
// that onPageStarted occurs after exec calls have started happening on a new page, which can cause the message queue
|
||||||
|
// to be reset between the queuing of a new message and its retrieval by javascript. To avoid this from happening,
|
||||||
|
// javascript always sends a "startup" exec upon loading a new page which causes all future exec calls to happen on the UI
|
||||||
|
// thread (and hence after onPageStarted) until there are no more pending exec calls remaining.
|
||||||
|
numPendingUiExecs.getAndIncrement();
|
||||||
|
ctx.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
numPendingUiExecs.getAndDecrement();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,40 +21,159 @@ package org.apache.cordova.api;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class PluginResult extends org.apache.cordova.PluginResult {
|
import android.util.Base64;
|
||||||
|
|
||||||
|
public class PluginResult {
|
||||||
|
private final int status;
|
||||||
|
private final int messageType;
|
||||||
|
private boolean keepCallback = false;
|
||||||
|
private String strMessage;
|
||||||
|
private String encodedMessage;
|
||||||
|
|
||||||
public PluginResult(Status status) {
|
public PluginResult(Status status) {
|
||||||
super(status);
|
this(status, PluginResult.StatusMessages[status.ordinal()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, String message) {
|
public PluginResult(Status status, String message) {
|
||||||
super(status, message);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = message == null ? MESSAGE_TYPE_NULL : MESSAGE_TYPE_STRING;
|
||||||
|
this.strMessage = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, JSONArray message) {
|
public PluginResult(Status status, JSONArray message) {
|
||||||
super(status, message);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_JSON;
|
||||||
|
encodedMessage = message.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, JSONObject message) {
|
public PluginResult(Status status, JSONObject message) {
|
||||||
super(status, message);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_JSON;
|
||||||
|
encodedMessage = message.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, int i) {
|
public PluginResult(Status status, int i) {
|
||||||
super(status, i);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_NUMBER;
|
||||||
|
this.encodedMessage = ""+i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, float f) {
|
public PluginResult(Status status, float f) {
|
||||||
super(status, f);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_NUMBER;
|
||||||
|
this.encodedMessage = ""+f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, boolean b) {
|
public PluginResult(Status status, boolean b) {
|
||||||
super(status, b);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_BOOLEAN;
|
||||||
|
this.encodedMessage = Boolean.toString(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, byte[] data) {
|
public PluginResult(Status status, byte[] data) {
|
||||||
super(status, data);
|
this(status, data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, byte[] data, boolean binaryString) {
|
public PluginResult(Status status, byte[] data, boolean binaryString) {
|
||||||
super(status, data, binaryString);
|
this.status = status.ordinal();
|
||||||
|
this.messageType = binaryString ? MESSAGE_TYPE_BINARYSTRING : MESSAGE_TYPE_ARRAYBUFFER;
|
||||||
|
this.encodedMessage = Base64.encodeToString(data, Base64.NO_WRAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeepCallback(boolean b) {
|
||||||
|
this.keepCallback = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMessageType() {
|
||||||
|
return messageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
if (encodedMessage == null) {
|
||||||
|
encodedMessage = JSONObject.quote(strMessage);
|
||||||
|
}
|
||||||
|
return encodedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If messageType == MESSAGE_TYPE_STRING, then returns the message string.
|
||||||
|
* Otherwise, returns null.
|
||||||
|
*/
|
||||||
|
public String getStrMessage() {
|
||||||
|
return strMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getKeepCallback() {
|
||||||
|
return this.keepCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
||||||
|
public String getJSONString() {
|
||||||
|
return "{\"status\":" + this.status + ",\"message\":" + this.getMessage() + ",\"keepCallback\":" + this.keepCallback + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
||||||
|
public String toCallbackString(String callbackId) {
|
||||||
|
// If no result to be sent and keeping callback, then no need to sent back to JavaScript
|
||||||
|
if ((status == PluginResult.Status.NO_RESULT.ordinal()) && keepCallback) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
|
||||||
|
if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
|
||||||
|
return toSuccessCallbackString(callbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toErrorCallbackString(callbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
||||||
|
public String toSuccessCallbackString(String callbackId) {
|
||||||
|
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // Use sendPluginResult instead of sendJavascript.
|
||||||
|
public String toErrorCallbackString(String callbackId) {
|
||||||
|
return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int MESSAGE_TYPE_STRING = 1;
|
||||||
|
public static final int MESSAGE_TYPE_JSON = 2;
|
||||||
|
public static final int MESSAGE_TYPE_NUMBER = 3;
|
||||||
|
public static final int MESSAGE_TYPE_BOOLEAN = 4;
|
||||||
|
public static final int MESSAGE_TYPE_NULL = 5;
|
||||||
|
public static final int MESSAGE_TYPE_ARRAYBUFFER = 6;
|
||||||
|
// Use BINARYSTRING when your string may contain null characters.
|
||||||
|
// This is required to work around a bug in the platform :(.
|
||||||
|
public static final int MESSAGE_TYPE_BINARYSTRING = 7;
|
||||||
|
|
||||||
|
public static String[] StatusMessages = new String[] {
|
||||||
|
"No result",
|
||||||
|
"OK",
|
||||||
|
"Class not found",
|
||||||
|
"Illegal access",
|
||||||
|
"Instantiation error",
|
||||||
|
"Malformed url",
|
||||||
|
"IO error",
|
||||||
|
"Invalid action",
|
||||||
|
"JSON error",
|
||||||
|
"Error"
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
NO_RESULT,
|
||||||
|
OK,
|
||||||
|
CLASS_NOT_FOUND_EXCEPTION,
|
||||||
|
ILLEGAL_ACCESS_EXCEPTION,
|
||||||
|
INSTANTIATION_EXCEPTION,
|
||||||
|
MALFORMED_URL_EXCEPTION,
|
||||||
|
IO_EXCEPTION,
|
||||||
|
INVALID_ACTION,
|
||||||
|
JSON_EXCEPTION,
|
||||||
|
ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user