You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2013/07/05 14:48:22 UTC
[41/51] [partial] Merge master2->master
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/ContactManager.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/ContactManager.java b/lib/cordova-android/framework/src/org/apache/cordova/ContactManager.java
deleted file mode 100755
index 8ea64a6..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/ContactManager.java
+++ /dev/null
@@ -1,122 +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.api.CallbackContext;
-import org.apache.cordova.api.CordovaPlugin;
-import org.apache.cordova.api.PluginResult;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import android.util.Log;
-
-public class ContactManager extends CordovaPlugin {
-
- private ContactAccessor contactAccessor;
- private static final String LOG_TAG = "Contact Query";
-
- public static final int UNKNOWN_ERROR = 0;
- public static final int INVALID_ARGUMENT_ERROR = 1;
- public static final int TIMEOUT_ERROR = 2;
- public static final int PENDING_OPERATION_ERROR = 3;
- public static final int IO_ERROR = 4;
- public static final int NOT_SUPPORTED_ERROR = 5;
- public static final int PERMISSION_DENIED_ERROR = 20;
-
- /**
- * Constructor.
- */
- public ContactManager() {
- }
-
- /**
- * Executes the request and returns PluginResult.
- *
- * @param action The action to execute.
- * @param args JSONArray of arguments for the plugin.
- * @param callbackContext The callback context used when calling back into JavaScript.
- * @return True if the action was valid, false otherwise.
- */
- public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
- /**
- * Check to see if we are on an Android 1.X device. If we are return an error as we
- * do not support this as of Cordova 1.0.
- */
- if (android.os.Build.VERSION.RELEASE.startsWith("1.")) {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ContactManager.NOT_SUPPORTED_ERROR));
- return true;
- }
-
- /**
- * Only create the contactAccessor after we check the Android version or the program will crash
- * older phones.
- */
- if (this.contactAccessor == null) {
- this.contactAccessor = new ContactAccessorSdk5(this.webView, this.cordova);
- }
-
- if (action.equals("search")) {
- final JSONArray filter = args.getJSONArray(0);
- final JSONObject options = args.getJSONObject(1);
- this.cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- JSONArray res = contactAccessor.search(filter, options);
- callbackContext.success(res);
- }
- });
- }
- else if (action.equals("save")) {
- final JSONObject contact = args.getJSONObject(0);
- this.cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- JSONObject res = null;
- String id = contactAccessor.save(contact);
- if (id != null) {
- try {
- res = contactAccessor.getContactById(id);
- } catch (JSONException e) {
- Log.e(LOG_TAG, "JSON fail.", e);
- }
- }
- if (res != null) {
- callbackContext.success(res);
- } else {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, UNKNOWN_ERROR));
- }
- }
- });
- }
- else if (action.equals("remove")) {
- final String contactId = args.getString(0);
- this.cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- if (contactAccessor.remove(contactId)) {
- callbackContext.success();
- } else {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, UNKNOWN_ERROR));
- }
- }
- });
- }
- else {
- return false;
- }
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
deleted file mode 100644
index d40d26e..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaArgs.java
+++ /dev/null
@@ -1,113 +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.JSONException;
-import org.json.JSONObject;
-
-import android.util.Base64;
-
-public class CordovaArgs {
- private JSONArray baseArgs;
-
- public CordovaArgs(JSONArray args) {
- this.baseArgs = args;
- }
-
-
- // Pass through the basics to the base args.
- public Object get(int index) throws JSONException {
- return baseArgs.get(index);
- }
-
- public boolean getBoolean(int index) throws JSONException {
- return baseArgs.getBoolean(index);
- }
-
- public double getDouble(int index) throws JSONException {
- return baseArgs.getDouble(index);
- }
-
- public int getInt(int index) throws JSONException {
- return baseArgs.getInt(index);
- }
-
- public JSONArray getJSONArray(int index) throws JSONException {
- return baseArgs.getJSONArray(index);
- }
-
- public JSONObject getJSONObject(int index) throws JSONException {
- return baseArgs.getJSONObject(index);
- }
-
- public long getLong(int index) throws JSONException {
- return baseArgs.getLong(index);
- }
-
- public String getString(int index) throws JSONException {
- return baseArgs.getString(index);
- }
-
-
- public Object opt(int index) {
- return baseArgs.opt(index);
- }
-
- public boolean optBoolean(int index) {
- return baseArgs.optBoolean(index);
- }
-
- public double optDouble(int index) {
- return baseArgs.optDouble(index);
- }
-
- public int optInt(int index) {
- return baseArgs.optInt(index);
- }
-
- public JSONArray optJSONArray(int index) {
- return baseArgs.optJSONArray(index);
- }
-
- public JSONObject optJSONObject(int index) {
- return baseArgs.optJSONObject(index);
- }
-
- public long optLong(int index) {
- return baseArgs.optLong(index);
- }
-
- public String optString(int index) {
- return baseArgs.optString(index);
- }
-
- public boolean isNull(int index) {
- return baseArgs.isNull(index);
- }
-
-
- // The interesting custom helpers.
- public byte[] getArrayBuffer(int index) throws JSONException {
- String encoded = baseArgs.getString(index);
- return Base64.decode(encoded, Base64.DEFAULT);
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
deleted file mode 100755
index fb6d45f..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ /dev/null
@@ -1,402 +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.api.CordovaInterface;
-import org.apache.cordova.api.LOG;
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.webkit.ConsoleMessage;
-import android.webkit.JsPromptResult;
-import android.webkit.JsResult;
-import android.webkit.ValueCallback;
-import android.webkit.WebChromeClient;
-import android.webkit.WebStorage;
-import android.webkit.WebView;
-import android.webkit.GeolocationPermissions.Callback;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
-
-/**
- * This class is the WebChromeClient that implements callbacks for our web view.
- */
-public class CordovaChromeClient extends WebChromeClient {
-
- public static final int FILECHOOSER_RESULTCODE = 5173;
- private static final String LOG_TAG = "CordovaChromeClient";
- private String TAG = "CordovaLog";
- private long MAX_QUOTA = 100 * 1024 * 1024;
- private CordovaInterface cordova;
- private CordovaWebView appView;
-
- // the video progress view
- private View mVideoProgressView;
-
- // File Chooser
- public ValueCallback<Uri> mUploadMessage;
-
- /**
- * Constructor.
- *
- * @param cordova
- */
- public CordovaChromeClient(CordovaInterface cordova) {
- this.cordova = cordova;
- }
-
- /**
- * Constructor.
- *
- * @param ctx
- * @param app
- */
- public CordovaChromeClient(CordovaInterface ctx, CordovaWebView app) {
- this.cordova = ctx;
- this.appView = app;
- }
-
- /**
- * Constructor.
- *
- * @param view
- */
- public void setWebView(CordovaWebView view) {
- this.appView = view;
- }
-
- /**
- * Tell the client to display a javascript alert dialog.
- *
- * @param view
- * @param url
- * @param message
- * @param result
- */
- @Override
- public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
- AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
- dlg.setMessage(message);
- dlg.setTitle("Alert");
- //Don't let alerts break the back button
- dlg.setCancelable(true);
- dlg.setPositiveButton(android.R.string.ok,
- new AlertDialog.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- result.confirm();
- }
- });
- dlg.setOnCancelListener(
- new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- result.cancel();
- }
- });
- dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
- //DO NOTHING
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK)
- {
- result.confirm();
- return false;
- }
- else
- return true;
- }
- });
- dlg.create();
- dlg.show();
- return true;
- }
-
- /**
- * Tell the client to display a confirm dialog to the user.
- *
- * @param view
- * @param url
- * @param message
- * @param result
- */
- @Override
- public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
- AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
- dlg.setMessage(message);
- dlg.setTitle("Confirm");
- dlg.setCancelable(true);
- dlg.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- result.confirm();
- }
- });
- dlg.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- result.cancel();
- }
- });
- dlg.setOnCancelListener(
- new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- result.cancel();
- }
- });
- dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
- //DO NOTHING
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK)
- {
- result.cancel();
- return false;
- }
- else
- return true;
- }
- });
- dlg.create();
- dlg.show();
- return true;
- }
-
- /**
- * Tell the client to display a prompt dialog to the user.
- * If the client returns true, WebView will assume that the client will
- * handle the prompt dialog and call the appropriate JsPromptResult method.
- *
- * Since we are hacking prompts for our own purposes, we should not be using them for
- * this purpose, perhaps we should hack console.log to do this instead!
- *
- * @param view
- * @param url
- * @param message
- * @param defaultValue
- * @param result
- */
- @Override
- public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
-
- // Security check to make sure any requests are coming from the page initially
- // loaded in webview and not another loaded in an iframe.
- boolean reqOk = false;
- if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
- reqOk = true;
- }
-
- // Calling PluginManager.exec() to call a native service using
- // prompt(this.stringify(args), "gap:"+this.stringify([service, action, callbackId, true]));
- if (reqOk && defaultValue != null && defaultValue.length() > 3 && defaultValue.substring(0, 4).equals("gap:")) {
- JSONArray array;
- try {
- array = new JSONArray(defaultValue.substring(4));
- String service = array.getString(0);
- String action = array.getString(1);
- String callbackId = array.getString(2);
- String r = this.appView.exposedJsApi.exec(service, action, callbackId, message);
- result.confirm(r == null ? "" : r);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- // Sets the native->JS bridge mode.
- else if (reqOk && defaultValue != null && defaultValue.equals("gap_bridge_mode:")) {
- this.appView.exposedJsApi.setNativeToJsBridgeMode(Integer.parseInt(message));
- result.confirm("");
- }
-
- // Polling for JavaScript messages
- else if (reqOk && defaultValue != null && defaultValue.equals("gap_poll:")) {
- String r = this.appView.exposedJsApi.retrieveJsMessages();
- result.confirm(r == null ? "" : r);
- }
-
- // Do NO-OP so older code doesn't display dialog
- else if (defaultValue != null && defaultValue.equals("gap_init:")) {
- result.confirm("OK");
- }
-
- // Show dialog
- else {
- final JsPromptResult res = result;
- AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
- dlg.setMessage(message);
- final EditText input = new EditText(this.cordova.getActivity());
- if (defaultValue != null) {
- input.setText(defaultValue);
- }
- dlg.setView(input);
- dlg.setCancelable(false);
- dlg.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- String usertext = input.getText().toString();
- res.confirm(usertext);
- }
- });
- dlg.setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- res.cancel();
- }
- });
- dlg.create();
- dlg.show();
- }
- return true;
- }
-
- /**
- * Handle database quota exceeded notification.
- *
- * @param url
- * @param databaseIdentifier
- * @param currentQuota
- * @param estimatedSize
- * @param totalUsedQuota
- * @param quotaUpdater
- */
- @Override
- public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
- long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
- {
- LOG.d(TAG, "DroidGap: onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
-
- if (estimatedSize < MAX_QUOTA)
- {
- //increase for 1Mb
- long newQuota = estimatedSize;
- LOG.d(TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
- quotaUpdater.updateQuota(newQuota);
- }
- else
- {
- // Set the quota to whatever it is and force an error
- // TODO: get docs on how to handle this properly
- quotaUpdater.updateQuota(currentQuota);
- }
- }
-
- // console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
- // Expect this to not compile in a future Android release!
- @SuppressWarnings("deprecation")
- @Override
- public void onConsoleMessage(String message, int lineNumber, String sourceID)
- {
- //This is only for Android 2.1
- if(android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.ECLAIR_MR1)
- {
- LOG.d(TAG, "%s: Line %d : %s", sourceID, lineNumber, message);
- super.onConsoleMessage(message, lineNumber, sourceID);
- }
- }
-
- @TargetApi(8)
- @Override
- public boolean onConsoleMessage(ConsoleMessage consoleMessage)
- {
- if (consoleMessage.message() != null)
- LOG.d(TAG, consoleMessage.message());
- return super.onConsoleMessage(consoleMessage);
- }
-
- @Override
- /**
- * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
- *
- * @param origin
- * @param callback
- */
- public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
- super.onGeolocationPermissionsShowPrompt(origin, callback);
- callback.invoke(origin, true, false);
- }
-
- // API level 7 is required for this, see if we could lower this using something else
- @Override
- public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
- this.appView.showCustomView(view, callback);
- }
-
- @Override
- public void onHideCustomView() {
- this.appView.hideCustomView();
- }
-
- @Override
- /**
- * Ask the host application for a custom progress view to show while
- * a <video> is loading.
- * @return View The progress view.
- */
- public View getVideoLoadingProgressView() {
-
- if (mVideoProgressView == null) {
- // Create a new Loading view programmatically.
-
- // create the linear layout
- LinearLayout layout = new LinearLayout(this.appView.getContext());
- layout.setOrientation(LinearLayout.VERTICAL);
- RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
- layout.setLayoutParams(layoutParams);
- // the proress bar
- ProgressBar bar = new ProgressBar(this.appView.getContext());
- LinearLayout.LayoutParams barLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- barLayoutParams.gravity = Gravity.CENTER;
- bar.setLayoutParams(barLayoutParams);
- layout.addView(bar);
-
- mVideoProgressView = layout;
- }
- return mVideoProgressView;
- }
-
- public void openFileChooser(ValueCallback<Uri> uploadMsg) {
- this.openFileChooser(uploadMsg, "*/*");
- }
-
- public void openFileChooser( ValueCallback<Uri> uploadMsg, String acceptType ) {
- this.openFileChooser(uploadMsg, acceptType, null);
- }
-
- public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
- {
- mUploadMessage = uploadMsg;
- Intent i = new Intent(Intent.ACTION_GET_CONTENT);
- i.addCategory(Intent.CATEGORY_OPENABLE);
- i.setType("*/*");
- this.cordova.getActivity().startActivityForResult(Intent.createChooser(i, "File Browser"),
- FILECHOOSER_RESULTCODE);
- }
-
- public ValueCallback<Uri> getValueCallback() {
- return this.mUploadMessage;
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/CordovaLocationListener.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaLocationListener.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaLocationListener.java
deleted file mode 100644
index 01c828b..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaLocationListener.java
+++ /dev/null
@@ -1,251 +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.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.apache.cordova.api.CallbackContext;
-
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.util.Log;
-
-public class CordovaLocationListener implements LocationListener {
- public static int PERMISSION_DENIED = 1;
- public static int POSITION_UNAVAILABLE = 2;
- public static int TIMEOUT = 3;
-
- protected LocationManager locationManager;
- private GeoBroker owner;
- protected boolean running = false;
-
- public HashMap<String, CallbackContext> watches = new HashMap<String, CallbackContext>();
- private List<CallbackContext> callbacks = new ArrayList<CallbackContext>();
-
- private Timer timer = null;
-
- private String TAG = "[Cordova Location Listener]";
-
- public CordovaLocationListener(LocationManager manager, GeoBroker broker, String tag) {
- this.locationManager = manager;
- this.owner = broker;
- this.TAG = tag;
- }
-
- protected void fail(int code, String message) {
- this.cancelTimer();
- for (CallbackContext callbackContext: this.callbacks)
- {
- this.owner.fail(code, message, callbackContext, false);
- }
- if(this.owner.isGlobalListener(this) && this.watches.size() == 0)
- {
- Log.d(TAG, "Stopping global listener");
- this.stop();
- }
- this.callbacks.clear();
-
- Iterator<CallbackContext> it = this.watches.values().iterator();
- while (it.hasNext()) {
- this.owner.fail(code, message, it.next(), true);
- }
- }
-
- private void win(Location loc) {
- this.cancelTimer();
- for (CallbackContext callbackContext: this.callbacks)
- {
- this.owner.win(loc, callbackContext, false);
- }
- if(this.owner.isGlobalListener(this) && this.watches.size() == 0)
- {
- Log.d(TAG, "Stopping global listener");
- this.stop();
- }
- this.callbacks.clear();
-
- Iterator<CallbackContext> it = this.watches.values().iterator();
- while (it.hasNext()) {
- this.owner.win(loc, it.next(), true);
- }
- }
-
- /**
- * Location Listener Methods
- */
-
- /**
- * Called when the provider is disabled by the user.
- *
- * @param provider
- */
- public void onProviderDisabled(String provider) {
- Log.d(TAG, "Location provider '" + provider + "' disabled.");
- this.fail(POSITION_UNAVAILABLE, "GPS provider disabled.");
- }
-
- /**
- * Called when the provider is enabled by the user.
- *
- * @param provider
- */
- public void onProviderEnabled(String provider) {
- Log.d(TAG, "Location provider "+ provider + " has been enabled");
- }
-
- /**
- * Called when the provider status changes. This method is called when a
- * provider is unable to fetch a location or if the provider has recently
- * become available after a period of unavailability.
- *
- * @param provider
- * @param status
- * @param extras
- */
- public void onStatusChanged(String provider, int status, Bundle extras) {
- Log.d(TAG, "The status of the provider " + provider + " has changed");
- if (status == 0) {
- Log.d(TAG, provider + " is OUT OF SERVICE");
- this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Provider " + provider + " is out of service.");
- }
- else if (status == 1) {
- Log.d(TAG, provider + " is TEMPORARILY_UNAVAILABLE");
- }
- else {
- Log.d(TAG, provider + " is AVAILABLE");
- }
- }
-
- /**
- * Called when the location has changed.
- *
- * @param location
- */
- public void onLocationChanged(Location location) {
- Log.d(TAG, "The location has been updated!");
- this.win(location);
- }
-
- // PUBLIC
-
- public int size() {
- return this.watches.size() + this.callbacks.size();
- }
-
- public void addWatch(String timerId, CallbackContext callbackContext) {
- this.watches.put(timerId, callbackContext);
- if (this.size() == 1) {
- this.start();
- }
- }
- public void addCallback(CallbackContext callbackContext, int timeout) {
- if(this.timer == null) {
- this.timer = new Timer();
- }
- this.timer.schedule(new LocationTimeoutTask(callbackContext, this), timeout);
- this.callbacks.add(callbackContext);
- if (this.size() == 1) {
- this.start();
- }
- }
- public void clearWatch(String timerId) {
- if (this.watches.containsKey(timerId)) {
- this.watches.remove(timerId);
- }
- if (this.size() == 0) {
- this.stop();
- }
- }
-
- /**
- * Destroy listener.
- */
- public void destroy() {
- this.stop();
- }
-
- // LOCAL
-
- /**
- * Start requesting location updates.
- *
- * @param interval
- */
- protected void start() {
- if (!this.running) {
- if (this.locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
- this.running = true;
- this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 10, this);
- } else {
- this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Network provider is not available.");
- }
- }
- }
-
- /**
- * Stop receiving location updates.
- */
- private void stop() {
- this.cancelTimer();
- if (this.running) {
- this.locationManager.removeUpdates(this);
- this.running = false;
- }
- }
-
- private void cancelTimer() {
- if(this.timer != null) {
- this.timer.cancel();
- this.timer.purge();
- this.timer = null;
- }
- }
-
- private class LocationTimeoutTask extends TimerTask {
-
- private CallbackContext callbackContext = null;
- private CordovaLocationListener listener = null;
-
- public LocationTimeoutTask(CallbackContext callbackContext, CordovaLocationListener listener) {
- this.callbackContext = callbackContext;
- this.listener = listener;
- }
-
- @Override
- public void run() {
- for (CallbackContext callbackContext: listener.callbacks) {
- if(this.callbackContext == callbackContext) {
- listener.callbacks.remove(callbackContext);
- break;
- }
- }
-
- if(listener.size() == 0) {
- listener.stop();
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
deleted file mode 100755
index 5dd061e..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
+++ /dev/null
@@ -1,945 +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.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Stack;
-import java.util.regex.Pattern;
-
-import org.apache.cordova.Config;
-import org.apache.cordova.api.CordovaInterface;
-import org.apache.cordova.api.LOG;
-import org.apache.cordova.api.PluginManager;
-import org.apache.cordova.api.PluginResult;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.WebBackForwardList;
-import android.webkit.WebHistoryItem;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebSettings.LayoutAlgorithm;
-import android.widget.FrameLayout;
-
-public class CordovaWebView extends WebView {
-
- public static final String TAG = "CordovaWebView";
-
- private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
- private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
-
- public PluginManager pluginManager;
- private boolean paused;
-
- private BroadcastReceiver receiver;
-
-
- /** Activities and other important classes **/
- private CordovaInterface cordova;
- CordovaWebViewClient viewClient;
- @SuppressWarnings("unused")
- private CordovaChromeClient chromeClient;
-
- private String url;
-
- // Flag to track that a loadUrl timeout occurred
- int loadUrlTimeout = 0;
-
- private boolean bound;
-
- private boolean handleButton = false;
-
- private long lastMenuEventTime = 0;
-
- NativeToJsMessageQueue jsMessageQueue;
- ExposedJsApi exposedJsApi;
-
- /** custom view created by the browser (a video player for example) */
- private View mCustomView;
- private WebChromeClient.CustomViewCallback mCustomViewCallback;
-
- private ActivityResult mResult = null;
-
- class ActivityResult {
-
- int request;
- int result;
- Intent incoming;
-
- public ActivityResult(int req, int res, Intent intent) {
- request = req;
- result = res;
- incoming = intent;
- }
-
-
- }
-
- static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
- new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
- Gravity.CENTER);
-
- /**
- * Constructor.
- *
- * @param context
- */
- public CordovaWebView(Context context) {
- super(context);
- if (CordovaInterface.class.isInstance(context))
- {
- this.cordova = (CordovaInterface) context;
- }
- else
- {
- Log.d(TAG, "Your activity must implement CordovaInterface to work");
- }
- this.loadConfiguration();
- this.setup();
- }
-
- /**
- * Constructor.
- *
- * @param context
- * @param attrs
- */
- public CordovaWebView(Context context, AttributeSet attrs) {
- super(context, attrs);
- if (CordovaInterface.class.isInstance(context))
- {
- this.cordova = (CordovaInterface) context;
- }
- else
- {
- Log.d(TAG, "Your activity must implement CordovaInterface to work");
- }
- this.setWebChromeClient(new CordovaChromeClient(this.cordova, this));
- this.initWebViewClient(this.cordova);
- this.loadConfiguration();
- this.setup();
- }
-
- /**
- * Constructor.
- *
- * @param context
- * @param attrs
- * @param defStyle
- *
- */
- public CordovaWebView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- if (CordovaInterface.class.isInstance(context))
- {
- this.cordova = (CordovaInterface) context;
- }
- else
- {
- Log.d(TAG, "Your activity must implement CordovaInterface to work");
- }
- this.setWebChromeClient(new CordovaChromeClient(this.cordova, this));
- this.loadConfiguration();
- this.setup();
- }
-
- /**
- * Constructor.
- *
- * @param context
- * @param attrs
- * @param defStyle
- * @param privateBrowsing
- */
- @TargetApi(11)
- public CordovaWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
- super(context, attrs, defStyle, privateBrowsing);
- if (CordovaInterface.class.isInstance(context))
- {
- this.cordova = (CordovaInterface) context;
- }
- else
- {
- Log.d(TAG, "Your activity must implement CordovaInterface to work");
- }
- this.setWebChromeClient(new CordovaChromeClient(this.cordova));
- this.initWebViewClient(this.cordova);
- this.loadConfiguration();
- this.setup();
- }
-
-
- private void initWebViewClient(CordovaInterface cordova) {
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB ||
- android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
- {
- this.setWebViewClient(new CordovaWebViewClient(this.cordova, this));
- }
- else
- {
- this.setWebViewClient(new IceCreamCordovaWebViewClient(this.cordova, this));
- }
- }
-
- /**
- * Initialize webview.
- */
- @SuppressWarnings("deprecation")
- @SuppressLint("NewApi")
- private void setup() {
- this.setInitialScale(0);
- this.setVerticalScrollBarEnabled(false);
- this.requestFocusFromTouch();
-
- // Enable JavaScript
- WebSettings settings = this.getSettings();
- settings.setJavaScriptEnabled(true);
- settings.setJavaScriptCanOpenWindowsAutomatically(true);
- settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
-
- // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2)
- try {
- Method gingerbread_getMethod = WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class });
-
- String manufacturer = android.os.Build.MANUFACTURER;
- Log.d(TAG, "CordovaWebView is running on device made by: " + manufacturer);
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB &&
- android.os.Build.MANUFACTURER.contains("HTC"))
- {
- gingerbread_getMethod.invoke(settings, true);
- }
- } catch (NoSuchMethodException e) {
- Log.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8");
- } catch (IllegalArgumentException e) {
- Log.d(TAG, "Doing the NavDump failed with bad arguments");
- } catch (IllegalAccessException e) {
- Log.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore");
- } catch (InvocationTargetException e) {
- Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore.");
- }
-
- //We don't save any form data in the application
- settings.setSaveFormData(false);
- settings.setSavePassword(false);
-
- // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
- // while we do this
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
- Level16Apis.enableUniversalAccess(settings);
- // Enable database
- // We keep this disabled because we use or shim to get around DOM_EXCEPTION_ERROR_16
- String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
- settings.setDatabaseEnabled(true);
- settings.setDatabasePath(databasePath);
-
- settings.setGeolocationDatabasePath(databasePath);
-
- // Enable DOM storage
- settings.setDomStorageEnabled(true);
-
- // Enable built-in geolocation
- settings.setGeolocationEnabled(true);
-
- // Enable AppCache
- // Fix for CB-2282
- settings.setAppCacheMaxSize(5 * 1048576);
- String pathToCache = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
- settings.setAppCachePath(pathToCache);
- settings.setAppCacheEnabled(true);
-
- // Fix for CB-1405
- // Google issue 4641
- this.updateUserAgentString();
-
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- if (this.receiver == null) {
- this.receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateUserAgentString();
- }
- };
- this.cordova.getActivity().registerReceiver(this.receiver, intentFilter);
- }
- // end CB-1405
-
- pluginManager = new PluginManager(this, this.cordova);
- jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
- exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue);
- exposeJsInterface();
- }
-
- private void updateUserAgentString() {
- this.getSettings().getUserAgentString();
- }
-
- private void exposeJsInterface() {
- int SDK_INT = Build.VERSION.SDK_INT;
- boolean isHoneycomb = (SDK_INT >= Build.VERSION_CODES.HONEYCOMB && SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2);
- if (isHoneycomb || (SDK_INT < Build.VERSION_CODES.GINGERBREAD)) {
- Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old.");
- // Bug being that Java Strings do not get converted to JS strings automatically.
- // This isn't hard to work-around on the JS side, but it's easier to just
- // use the prompt bridge instead.
- return;
- } else if (SDK_INT < Build.VERSION_CODES.HONEYCOMB && Build.MANUFACTURER.equals("unknown")) {
- // addJavascriptInterface crashes on the 2.3 emulator.
- Log.i(TAG, "Disabled addJavascriptInterface() bridge callback due to a bug on the 2.3 emulator");
- return;
- }
- this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
- }
-
- /**
- * Set the WebViewClient.
- *
- * @param client
- */
- public void setWebViewClient(CordovaWebViewClient client) {
- this.viewClient = client;
- super.setWebViewClient(client);
- }
-
- /**
- * Set the WebChromeClient.
- *
- * @param client
- */
- public void setWebChromeClient(CordovaChromeClient client) {
- this.chromeClient = client;
- super.setWebChromeClient(client);
- }
-
- public CordovaChromeClient getWebChromeClient() {
- return this.chromeClient;
- }
-
- /**
- * Load the url into the webview.
- *
- * @param url
- */
- @Override
- public void loadUrl(String url) {
- if (url.equals("about:blank") || url.startsWith("javascript:")) {
- this.loadUrlNow(url);
- }
- else {
-
- String initUrl = this.getProperty("url", null);
-
- // If first page of app, then set URL to load to be the one passed in
- if (initUrl == null) {
- this.loadUrlIntoView(url);
- }
- // Otherwise use the URL specified in the activity's extras bundle
- else {
- this.loadUrlIntoView(initUrl);
- }
- }
- }
-
- /**
- * Load the url into the webview after waiting for period of time.
- * This is used to display the splashscreen for certain amount of time.
- *
- * @param url
- * @param time The number of ms to wait before loading webview
- */
- public void loadUrl(final String url, int time) {
- String initUrl = this.getProperty("url", null);
-
- // If first page of app, then set URL to load to be the one passed in
- if (initUrl == null) {
- this.loadUrlIntoView(url, time);
- }
- // Otherwise use the URL specified in the activity's extras bundle
- else {
- this.loadUrlIntoView(initUrl);
- }
- }
-
- /**
- * Load the url into the webview.
- *
- * @param url
- */
- public void loadUrlIntoView(final String url) {
- LOG.d(TAG, ">>> loadUrl(" + url + ")");
-
- this.url = url;
- this.pluginManager.init();
-
-
- // Create a timeout timer for loadUrl
- final CordovaWebView me = this;
- final int currentLoadUrlTimeout = me.loadUrlTimeout;
- final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("loadUrlTimeoutValue", "20000"));
-
- // Timeout error method
- final Runnable loadError = new Runnable() {
- public void run() {
- me.stopLoading();
- LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
- if (viewClient != null) {
- viewClient.onReceivedError(me, -6, "The connection to the server was unsuccessful.", url);
- }
- }
- };
-
- // Timeout timer method
- final Runnable timeoutCheck = new Runnable() {
- public void run() {
- try {
- synchronized (this) {
- wait(loadUrlTimeoutValue);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- // If timeout, then stop loading and handle error
- if (me.loadUrlTimeout == currentLoadUrlTimeout) {
- me.cordova.getActivity().runOnUiThread(loadError);
- }
- }
- };
-
- // Load url
- this.cordova.getActivity().runOnUiThread(new Runnable() {
- public void run() {
- Thread thread = new Thread(timeoutCheck);
- thread.start();
- me.loadUrlNow(url);
- }
- });
- }
-
- /**
- * Load URL in webview.
- *
- * @param url
- */
- void loadUrlNow(String url) {
- if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
- LOG.d(TAG, ">>> loadUrlNow()");
- }
- if (url.startsWith("file://") || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
- super.loadUrl(url);
- }
- }
-
- /**
- * Load the url into the webview after waiting for period of time.
- * This is used to display the splashscreen for certain amount of time.
- *
- * @param url
- * @param time The number of ms to wait before loading webview
- */
- public void loadUrlIntoView(final String url, final int time) {
-
- // If not first page of app, then load immediately
- // Add support for browser history if we use it.
- if ((url.startsWith("javascript:")) || this.canGoBack()) {
- }
-
- // If first page, then show splashscreen
- else {
-
- LOG.d(TAG, "DroidGap.loadUrl(%s, %d)", url, time);
-
- // Send message to show splashscreen now if desired
- this.postMessage("splashscreen", "show");
- }
-
- // Load url
- this.loadUrlIntoView(url);
- }
-
- /**
- * Send JavaScript statement back to JavaScript.
- * (This is a convenience method)
- *
- * @param message
- */
- public void sendJavascript(String statement) {
- this.jsMessageQueue.addJavaScript(statement);
- }
-
- /**
- * Send a plugin result back to JavaScript.
- * (This is a convenience method)
- *
- * @param message
- */
- public void sendPluginResult(PluginResult result, String callbackId) {
- this.jsMessageQueue.addPluginResult(result, callbackId);
- }
-
- /**
- * Send a message to all plugins.
- *
- * @param id The message id
- * @param data The message data
- */
- public void postMessage(String id, Object data) {
- if (this.pluginManager != null) {
- this.pluginManager.postMessage(id, data);
- }
- }
-
-
- /**
- * Go to previous page in history. (We manage our own history)
- *
- * @return true if we went back, false if we are already at top
- */
- public boolean backHistory() {
-
- // Check webview first to see if there is a history
- // This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
- if (super.canGoBack()) {
- printBackForwardList();
- super.goBack();
-
- return true;
- }
- return false;
- }
-
-
- /**
- * Load the specified URL in the Cordova webview or a new browser instance.
- *
- * NOTE: If openExternal is false, only URLs listed in whitelist can be loaded.
- *
- * @param url The url to load.
- * @param openExternal Load url in browser instead of Cordova webview.
- * @param clearHistory Clear the history stack, so new page becomes top of history
- * @param params DroidGap parameters for new app
- */
- public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) {
- LOG.d(TAG, "showWebPage(%s, %b, %b, HashMap", url, openExternal, clearHistory);
-
- // If clearing history
- if (clearHistory) {
- this.clearHistory();
- }
-
- // If loading into our webview
- if (!openExternal) {
-
- // Make sure url is in whitelist
- if (url.startsWith("file://") || Config.isUrlWhiteListed(url)) {
- // TODO: What about params?
- // Load new URL
- this.loadUrl(url);
- }
- // Load in default viewer if not
- else {
- LOG.w(TAG, "showWebPage: Cannot load URL into webview since it is not in white list. Loading into browser instead. (URL=" + url + ")");
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error loading url " + url, e);
- }
- }
- }
-
- // Load in default view intent
- else {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error loading url " + url, e);
- }
- }
- }
-
- /**
- * Check configuration parameters from Config.
- * Approved list of URLs that can be loaded into DroidGap
- * <access origin="http://server regexp" subdomains="true" />
- * Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
- * <log level="DEBUG" />
- */
- private void loadConfiguration() {
-
- if ("true".equals(this.getProperty("fullscreen", "false"))) {
- this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
- this.cordova.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
- }
-
- /**
- * Get string property for activity.
- *
- * @param name
- * @param defaultValue
- * @return
- */
- public String getProperty(String name, String defaultValue) {
- Bundle bundle = this.cordova.getActivity().getIntent().getExtras();
- if (bundle == null) {
- return defaultValue;
- }
- Object p = bundle.get(name);
- if (p == null) {
- return defaultValue;
- }
- return p.toString();
- }
-
- /*
- * onKeyDown
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- if(keyDownCodes.contains(keyCode))
- {
- if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
- // only override default behavior is event bound
- LOG.d(TAG, "Down Key Hit");
- this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');");
- return true;
- }
- // If volumeup key
- else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
- LOG.d(TAG, "Up Key Hit");
- this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');");
- return true;
- }
- else
- {
- return super.onKeyDown(keyCode, event);
- }
- }
- else if(keyCode == KeyEvent.KEYCODE_BACK)
- {
- return !(this.startOfHistory()) || this.bound;
- }
- else if(keyCode == KeyEvent.KEYCODE_MENU)
- {
- //How did we get here? Is there a childView?
- View childView = this.getFocusedChild();
- if(childView != null)
- {
- //Make sure we close the keyboard if it's present
- InputMethodManager imm = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(childView.getWindowToken(), 0);
- cordova.getActivity().openOptionsMenu();
- }
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event)
- {
- // If back key
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- // A custom view is currently displayed (e.g. playing a video)
- if(mCustomView != null) {
- this.hideCustomView();
- } else {
- // The webview is currently displayed
- // If back key is bound, then send event to JavaScript
- if (this.bound) {
- this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
- return true;
- } else {
- // If not bound
- // Go to previous page in webview if it is possible to go back
- if (this.backHistory()) {
- return true;
- }
- // If not, then invoke default behaviour
- else {
- //this.activityState = ACTIVITY_EXITING;
- //return false;
- // If they hit back button when app is initializing, app should exit instead of hang until initilazation (CB2-458)
- this.cordova.getActivity().finish();
- }
- }
- }
- }
- // Legacy
- else if (keyCode == KeyEvent.KEYCODE_MENU) {
- if (this.lastMenuEventTime < event.getEventTime()) {
- this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
- }
- this.lastMenuEventTime = event.getEventTime();
- return super.onKeyUp(keyCode, event);
- }
- // If search key
- else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
- this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
- return true;
- }
- else if(keyUpCodes.contains(keyCode))
- {
- //What the hell should this do?
- return super.onKeyUp(keyCode, event);
- }
-
- //Does webkit change this behavior?
- return super.onKeyUp(keyCode, event);
- }
-
-
- public void bindButton(boolean override)
- {
- this.bound = override;
- }
-
- public void bindButton(String button, boolean override) {
- // TODO Auto-generated method stub
- if (button.compareTo("volumeup")==0) {
- keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_UP);
- }
- else if (button.compareTo("volumedown")==0) {
- keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_DOWN);
- }
- }
-
- public void bindButton(int keyCode, boolean keyDown, boolean override) {
- if(keyDown)
- {
- keyDownCodes.add(keyCode);
- }
- else
- {
- keyUpCodes.add(keyCode);
- }
- }
-
- public boolean isBackButtonBound()
- {
- return this.bound;
- }
-
- public void handlePause(boolean keepRunning)
- {
- LOG.d(TAG, "Handle the pause");
- // Send pause event to JavaScript
- this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
-
- // Forward to plugins
- if (this.pluginManager != null) {
- this.pluginManager.onPause(keepRunning);
- }
-
- // If app doesn't want to run in background
- if (!keepRunning) {
- // Pause JavaScript timers (including setInterval)
- this.pauseTimers();
- }
- paused = true;
-
- }
-
- public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
- {
-
- this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
-
- // Forward to plugins
- if (this.pluginManager != null) {
- this.pluginManager.onResume(keepRunning);
- }
-
- // Resume JavaScript timers (including setInterval)
- this.resumeTimers();
- paused = false;
- }
-
- public void handleDestroy()
- {
- // Send destroy event to JavaScript
- // Since baseUrl is set in loadUrlIntoView, if user hit Back button before loadUrl was called, we'll get an NPE on baseUrl (CB-2458)
- this.loadUrlIntoView("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
-
- // Load blank page so that JavaScript onunload is called
- this.loadUrl("about:blank");
-
- // Forward to plugins
- if (this.pluginManager != null) {
- this.pluginManager.onDestroy();
- }
-
- // unregister the receiver
- if (this.receiver != null) {
- try {
- this.cordova.getActivity().unregisterReceiver(this.receiver);
- } catch (Exception e) {
- Log.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e);
- }
- }
- }
-
- public void onNewIntent(Intent intent)
- {
- //Forward to plugins
- if (this.pluginManager != null) {
- this.pluginManager.onNewIntent(intent);
- }
- }
-
- public boolean isPaused()
- {
- return paused;
- }
-
- public boolean hadKeyEvent() {
- return handleButton;
- }
-
- // Wrapping these functions in their own class prevents warnings in adb like:
- // VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
- @TargetApi(16)
- private static class Level16Apis {
- static void enableUniversalAccess(WebSettings settings) {
- settings.setAllowUniversalAccessFromFileURLs(true);
- }
- }
-
- public void printBackForwardList() {
- WebBackForwardList currentList = this.copyBackForwardList();
- int currentSize = currentList.getSize();
- for(int i = 0; i < currentSize; ++i)
- {
- WebHistoryItem item = currentList.getItemAtIndex(i);
- String url = item.getUrl();
- LOG.d(TAG, "The URL at index: " + Integer.toString(i) + "is " + url );
- }
- }
-
-
- //Can Go Back is BROKEN!
- public boolean startOfHistory()
- {
- WebBackForwardList currentList = this.copyBackForwardList();
- WebHistoryItem item = currentList.getItemAtIndex(0);
- if( item!=null){ // Null-fence in case they haven't called loadUrl yet (CB-2458)
- String url = item.getUrl();
- String currentUrl = this.getUrl();
- LOG.d(TAG, "The current URL is: " + currentUrl);
- LOG.d(TAG, "The URL at item 0 is:" + url);
- return currentUrl.equals(url);
- }
- return false;
- }
-
- public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {
- // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
- Log.d(TAG, "showing Custom View");
- // if a view already exists then immediately terminate the new one
- if (mCustomView != null) {
- callback.onCustomViewHidden();
- return;
- }
-
- // Store the view and its callback for later (to kill it properly)
- mCustomView = view;
- mCustomViewCallback = callback;
-
- // Add the custom view to its container.
- ViewGroup parent = (ViewGroup) this.getParent();
- parent.addView(view, COVER_SCREEN_GRAVITY_CENTER);
-
- // Hide the content view.
- this.setVisibility(View.GONE);
-
- // Finally show the custom view container.
- parent.setVisibility(View.VISIBLE);
- parent.bringToFront();
- }
-
- public void hideCustomView() {
- // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0
- Log.d(TAG, "Hidding Custom View");
- if (mCustomView == null) return;
-
- // Hide the custom view.
- mCustomView.setVisibility(View.GONE);
-
- // Remove the custom view from its container.
- ViewGroup parent = (ViewGroup) this.getParent();
- parent.removeView(mCustomView);
- mCustomView = null;
- mCustomViewCallback.onCustomViewHidden();
-
- // Show the content view.
- this.setVisibility(View.VISIBLE);
- }
-
- /**
- * if the video overlay is showing then we need to know
- * as it effects back button handling
- *
- * @return
- */
- public boolean isCustomViewShowing() {
- return mCustomView != null;
- }
-
- public WebBackForwardList restoreState(Bundle savedInstanceState)
- {
- WebBackForwardList myList = super.restoreState(savedInstanceState);
- Log.d(TAG, "WebView restoration crew now restoring!");
- //Initialize the plugin manager once more
- this.pluginManager.init();
- return myList;
- }
-
- public void storeResult(int requestCode, int resultCode, Intent intent) {
- mResult = new ActivityResult(requestCode, resultCode, intent);
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ac0c95be/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
deleted file mode 100755
index 4b00615..0000000
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ /dev/null
@@ -1,479 +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.ByteArrayInputStream;
-import java.util.Hashtable;
-
-import org.apache.cordova.api.CordovaInterface;
-
-import org.apache.cordova.api.LOG;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.annotation.TargetApi;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.net.http.SslError;
-import android.util.Log;
-import android.view.View;
-import android.webkit.HttpAuthHandler;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebResourceResponse;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-/**
- * This class is the WebViewClient that implements callbacks for our web view.
- */
-public class CordovaWebViewClient extends WebViewClient {
-
- private static final String TAG = "Cordova";
- private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";
- CordovaInterface cordova;
- CordovaWebView appView;
- private boolean doClearHistory = false;
-
- /** The authorization tokens. */
- private Hashtable<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
-
- /**
- * Constructor.
- *
- * @param cordova
- */
- public CordovaWebViewClient(CordovaInterface cordova) {
- this.cordova = cordova;
- }
-
- /**
- * Constructor.
- *
- * @param cordova
- * @param view
- */
- public CordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
- this.cordova = cordova;
- this.appView = view;
- }
-
- /**
- * Constructor.
- *
- * @param view
- */
- public void setWebView(CordovaWebView view) {
- this.appView = view;
- }
-
-
- // Parses commands sent by setting the webView's URL to:
- // cdvbrg:service/action/callbackId#jsonArgs
- private void handleExecUrl(String url) {
- int idx1 = CORDOVA_EXEC_URL_PREFIX.length();
- int idx2 = url.indexOf('#', idx1 + 1);
- int idx3 = url.indexOf('#', idx2 + 1);
- int idx4 = url.indexOf('#', idx3 + 1);
- if (idx1 == -1 || idx2 == -1 || idx3 == -1 || idx4 == -1) {
- Log.e(TAG, "Could not decode URL command: " + url);
- return;
- }
- String service = url.substring(idx1, idx2);
- String action = url.substring(idx2 + 1, idx3);
- String callbackId = url.substring(idx3 + 1, idx4);
- String jsonArgs = url.substring(idx4 + 1);
- appView.pluginManager.exec(service, action, callbackId, jsonArgs);
- }
-
- /**
- * Give the host application a chance to take over the control when a new url
- * is about to be loaded in the current WebView.
- *
- * @param view The WebView that is initiating the callback.
- * @param url The url to be loaded.
- * @return true to override, false for default behavior
- */
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- // Check if it's an exec() bridge command message.
- if (NativeToJsMessageQueue.ENABLE_LOCATION_CHANGE_EXEC_MODE && url.startsWith(CORDOVA_EXEC_URL_PREFIX)) {
- handleExecUrl(url);
- }
-
- // Give plugins the chance to handle the url
- else if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
- }
-
- // If dialing phone (tel:5551212)
- else if (url.startsWith(WebView.SCHEME_TEL)) {
- try {
- Intent intent = new Intent(Intent.ACTION_DIAL);
- intent.setData(Uri.parse(url));
- this.cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error dialing " + url + ": " + e.toString());
- }
- }
-
- // If displaying map (geo:0,0?q=address)
- else if (url.startsWith("geo:")) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- this.cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error showing map " + url + ": " + e.toString());
- }
- }
-
- // If sending email (mailto:abc@corp.com)
- else if (url.startsWith(WebView.SCHEME_MAILTO)) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- this.cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error sending email " + url + ": " + e.toString());
- }
- }
-
- // If sms:5551212?body=This is the message
- else if (url.startsWith("sms:")) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
-
- // Get address
- String address = null;
- int parmIndex = url.indexOf('?');
- if (parmIndex == -1) {
- address = url.substring(4);
- }
- else {
- address = url.substring(4, parmIndex);
-
- // If body, then set sms body
- Uri uri = Uri.parse(url);
- String query = uri.getQuery();
- if (query != null) {
- if (query.startsWith("body=")) {
- intent.putExtra("sms_body", query.substring(5));
- }
- }
- }
- intent.setData(Uri.parse("sms:" + address));
- intent.putExtra("address", address);
- intent.setType("vnd.android-dir/mms-sms");
- this.cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error sending sms " + url + ":" + e.toString());
- }
- }
-
- // All else
- else {
-
- // If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
- // Our app continues to run. When BACK is pressed, our app is redisplayed.
- if (url.startsWith("file://") || url.startsWith("data:") || Config.isUrlWhiteListed(url)) {
- return false;
- }
-
- // If not our application, let default viewer handle
- else {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- this.cordova.getActivity().startActivity(intent);
- } catch (android.content.ActivityNotFoundException e) {
- LOG.e(TAG, "Error loading url " + url, e);
- }
- }
- }
- return true;
- }
-
- /**
- * Check for intercepting any requests for resources.
- * This includes images and scripts and so on, not just top-level pages.
- * @param view The WebView.
- * @param url The URL to be loaded.
- * @return Either null to proceed as normal, or a WebResourceResponse.
- */
- @Override
- public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- //If something isn't whitelisted, just send a blank response
- if(!Config.isUrlWhiteListed(url) && (url.startsWith("http://") || url.startsWith("https://")))
- {
- return getWhitelistResponse();
- }
- if (this.appView.pluginManager != null) {
- return this.appView.pluginManager.shouldInterceptRequest(url);
- }
- return null;
- }
-
- private WebResourceResponse getWhitelistResponse()
- {
- WebResourceResponse emptyResponse;
- String empty = "";
- ByteArrayInputStream data = new ByteArrayInputStream(empty.getBytes());
- return new WebResourceResponse("text/plain", "UTF-8", data);
- }
-
- /**
- * On received http auth request.
- * The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
- *
- * @param view
- * @param handler
- * @param host
- * @param realm
- */
- @Override
- public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
-
- // Get the authentication token
- AuthenticationToken token = this.getAuthenticationToken(host, realm);
- if (token != null) {
- handler.proceed(token.getUserName(), token.getPassword());
- }
- else {
- // Handle 401 like we'd normally do!
- super.onReceivedHttpAuthRequest(view, handler, host, realm);
- }
- }
-
- /**
- * Notify the host application that a page has started loading.
- * This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted
- * one time for the main frame. This also means that onPageStarted will not be called when the contents of an
- * embedded frame changes, i.e. clicking a link whose target is an iframe.
- *
- * @param view The webview initiating the callback.
- * @param url The url of the page.
- */
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
-
- // Flush stale messages.
- this.appView.jsMessageQueue.reset();
-
- // Broadcast message that page has loaded
- this.appView.postMessage("onPageStarted", url);
-
- // Notify all plugins of the navigation, so they can clean up if necessary.
- if (this.appView.pluginManager != null) {
- this.appView.pluginManager.onReset();
- }
- }
-
- /**
- * Notify the host application that a page has finished loading.
- * This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet.
- *
- *
- * @param view The webview initiating the callback.
- * @param url The url of the page.
- */
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- LOG.d(TAG, "onPageFinished(" + url + ")");
-
- /**
- * Because of a timing issue we need to clear this history in onPageFinished as well as
- * onPageStarted. However we only want to do this if the doClearHistory boolean is set to
- * true. You see when you load a url with a # in it which is common in jQuery applications
- * onPageStared is not called. Clearing the history at that point would break jQuery apps.
- */
- if (this.doClearHistory) {
- view.clearHistory();
- this.doClearHistory = false;
- }
-
- // Clear timeout flag
- this.appView.loadUrlTimeout++;
-
- // Broadcast message that page has loaded
- this.appView.postMessage("onPageFinished", url);
-
- // Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
- if (this.appView.getVisibility() == View.INVISIBLE) {
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- Thread.sleep(2000);
- cordova.getActivity().runOnUiThread(new Runnable() {
- public void run() {
- appView.postMessage("spinner", "stop");
- }
- });
- } catch (InterruptedException e) {
- }
- }
- });
- t.start();
- }
-
- // Shutdown if blank loaded
- if (url.equals("about:blank")) {
- appView.postMessage("exit", null);
- }
- }
-
- /**
- * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable).
- * The errorCode parameter corresponds to one of the ERROR_* constants.
- *
- * @param view The WebView that is initiating the callback.
- * @param errorCode The error code corresponding to an ERROR_* value.
- * @param description A String describing the error.
- * @param failingUrl The url that failed to load.
- */
- @Override
- public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
- LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
-
- // Clear timeout flag
- this.appView.loadUrlTimeout++;
-
- // Handle error
- JSONObject data = new JSONObject();
- try {
- data.put("errorCode", errorCode);
- data.put("description", description);
- data.put("url", failingUrl);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- this.appView.postMessage("onReceivedError", data);
- }
-
- /**
- * Notify the host application that an SSL error occurred while loading a resource.
- * The host application must call either handler.cancel() or handler.proceed().
- * Note that the decision may be retained for use in response to future SSL errors.
- * The default behavior is to cancel the load.
- *
- * @param view The WebView that is initiating the callback.
- * @param handler An SslErrorHandler object that will handle the user's response.
- * @param error The SSL error object.
- */
- @TargetApi(8)
- @Override
- public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-
- final String packageName = this.cordova.getActivity().getPackageName();
- final PackageManager pm = this.cordova.getActivity().getPackageManager();
-
- ApplicationInfo appInfo;
- try {
- appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
- if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
- // debug = true
- handler.proceed();
- return;
- } else {
- // debug = false
- super.onReceivedSslError(view, handler, error);
- }
- } catch (NameNotFoundException e) {
- // When it doubt, lock it out!
- super.onReceivedSslError(view, handler, error);
- }
- }
-
-
- /**
- * Sets the authentication token.
- *
- * @param authenticationToken
- * @param host
- * @param realm
- */
- public void setAuthenticationToken(AuthenticationToken authenticationToken, String host, String realm) {
- if (host == null) {
- host = "";
- }
- if (realm == null) {
- realm = "";
- }
- this.authenticationTokens.put(host.concat(realm), authenticationToken);
- }
-
- /**
- * Removes the authentication token.
- *
- * @param host
- * @param realm
- *
- * @return the authentication token or null if did not exist
- */
- public AuthenticationToken removeAuthenticationToken(String host, String realm) {
- return this.authenticationTokens.remove(host.concat(realm));
- }
-
- /**
- * Gets the authentication token.
- *
- * In order it tries:
- * 1- host + realm
- * 2- host
- * 3- realm
- * 4- no host, no realm
- *
- * @param host
- * @param realm
- *
- * @return the authentication token
- */
- public AuthenticationToken getAuthenticationToken(String host, String realm) {
- AuthenticationToken token = null;
- token = this.authenticationTokens.get(host.concat(realm));
-
- if (token == null) {
- // try with just the host
- token = this.authenticationTokens.get(host);
-
- // Try the realm
- if (token == null) {
- token = this.authenticationTokens.get(realm);
- }
-
- // if no host found, just query for default
- if (token == null) {
- token = this.authenticationTokens.get("");
- }
- }
-
- return token;
- }
-
- /**
- * Clear all authentication tokens.
- */
- public void clearAuthenticationTokens() {
- this.authenticationTokens.clear();
- }
-
-}