mirror of
https://github.com/apache/cordova-android.git
synced 2025-03-14 07:11:04 +08:00
Merge branch 'master' into 4.0.x (file input, auth dialogs)
Conflicts: framework/src/org/apache/cordova/AndroidChromeClient.java framework/src/org/apache/cordova/CordovaActivity.java framework/src/org/apache/cordova/SplashScreenInternal.java
This commit is contained in:
commit
3949d9633c
@ -1,4 +1,5 @@
|
||||
language: android
|
||||
sudo: false
|
||||
install: npm install
|
||||
script:
|
||||
- npm test
|
||||
|
@ -22,10 +22,14 @@ import org.apache.cordova.CordovaInterface;
|
||||
import org.apache.cordova.LOG;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
@ -68,9 +72,6 @@ public class AndroidChromeClient extends WebChromeClient {
|
||||
//Keep track of last AlertDialog showed
|
||||
private AlertDialog lastHandledDialog;
|
||||
|
||||
// File Chooser
|
||||
protected ValueCallback<Uri> mUploadMessage;
|
||||
|
||||
public AndroidChromeClient(CordovaInterface ctx, AndroidWebView app) {
|
||||
this.cordova = ctx;
|
||||
this.appView = app;
|
||||
@ -299,7 +300,10 @@ public class AndroidChromeClient extends WebChromeClient {
|
||||
}
|
||||
return mVideoProgressView;
|
||||
}
|
||||
|
||||
|
||||
// <input type=file> support:
|
||||
// openFileChooser() is for pre KitKat and in KitKat mr1 (it's known broken in KitKat).
|
||||
// For Lollipop, we use onShowFileChooser().
|
||||
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
|
||||
this.openFileChooser(uploadMsg, "*/*");
|
||||
}
|
||||
@ -308,14 +312,39 @@ public class AndroidChromeClient extends WebChromeClient {
|
||||
this.openFileChooser(uploadMsg, acceptType, null);
|
||||
}
|
||||
|
||||
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
|
||||
public void openFileChooser(final 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);
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
cordova.startActivityForResult(new CordovaPlugin() {
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
|
||||
Log.d(LOG_TAG, "Receive file chooser URL: " + result);
|
||||
uploadMsg.onReceiveValue(result);
|
||||
}
|
||||
}, intent, FILECHOOSER_RESULTCODE);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
|
||||
Intent intent = fileChooserParams.createIntent();
|
||||
try {
|
||||
cordova.startActivityForResult(new CordovaPlugin() {
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent);
|
||||
Log.d(LOG_TAG, "Receive file chooser URL: " + result);
|
||||
filePathsCallback.onReceiveValue(result);
|
||||
}
|
||||
}, intent, FILECHOOSER_RESULTCODE);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w("No activity found to handle file chooser intent.", e);
|
||||
filePathsCallback.onReceiveValue(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void destroyLastDialog(){
|
||||
|
@ -798,14 +798,6 @@ public class AndroidWebView extends WebView implements CordovaWebView {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFilePickerResult(Uri uri) {
|
||||
if (null == chromeClient.mUploadMessage)
|
||||
return;
|
||||
chromeClient.mUploadMessage.onReceiveValue(uri);
|
||||
chromeClient.mUploadMessage = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postMessage(String id, Object data) {
|
||||
return pluginManager.postMessage(id, data);
|
||||
|
@ -86,15 +86,22 @@ public class AndroidWebViewClient extends WebViewClient {
|
||||
@Override
|
||||
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
|
||||
|
||||
// Get the authentication token
|
||||
// Get the authentication token (if specified)
|
||||
AuthenticationToken token = this.getAuthenticationToken(host, realm);
|
||||
if (token != null) {
|
||||
handler.proceed(token.getUserName(), token.getPassword());
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Handle 401 like we'd normally do!
|
||||
super.onReceivedHttpAuthRequest(view, handler, host, realm);
|
||||
|
||||
// Check if there is some plugin which can resolve this auth challenge
|
||||
PluginManager pluginManager = this.appView.pluginManager;
|
||||
if (pluginManager != null && pluginManager.onReceivedHttpAuthRequest(this.appView, new CordovaHttpAuthHandler(handler), host, realm)) {
|
||||
this.appView.loadUrlTimeout++;
|
||||
return;
|
||||
}
|
||||
|
||||
// By default handle 401 like we'd normally do!
|
||||
super.onReceivedHttpAuthRequest(view, handler, host, realm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,6 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
@ -95,7 +94,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
private int activityState = 0; // 0=starting, 1=running (after 1st resume), 2=shutting down
|
||||
|
||||
// Plugin to call when activity result is received
|
||||
protected CordovaPlugin activityResultCallback = null;
|
||||
protected int activityResultRequestCode;
|
||||
protected CordovaPlugin activityResultCallback;
|
||||
protected boolean activityResultKeepRunning;
|
||||
|
||||
/*
|
||||
@ -381,7 +381,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
* @param requestCode The request code that is passed to callback to identify the activity
|
||||
*/
|
||||
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
|
||||
this.activityResultCallback = command;
|
||||
setActivityResultCallback(command);
|
||||
this.activityResultKeepRunning = this.keepRunning;
|
||||
|
||||
// If multitasking turned on, then disable it for activities that return results
|
||||
@ -389,8 +389,19 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
this.keepRunning = false;
|
||||
}
|
||||
|
||||
// Start activity
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
try {
|
||||
startActivityForResult(intent, requestCode);
|
||||
} catch (RuntimeException e) { // E.g.: ActivityNotFoundException
|
||||
activityResultCallback = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
|
||||
// Capture requestCode here so that it is captured in the setActivityResultCallback() case.
|
||||
activityResultRequestCode = requestCode;
|
||||
super.startActivityForResult(intent, requestCode, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,32 +411,34 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
* @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").
|
||||
* @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
||||
*/
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
LOG.d(TAG, "Incoming Result");
|
||||
LOG.d(TAG, "Incoming Result. Request code = " + requestCode);
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
Log.d(TAG, "Request code = " + requestCode);
|
||||
if (appView != null && requestCode == AndroidChromeClient.FILECHOOSER_RESULTCODE) {
|
||||
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
|
||||
appView.onFilePickerResult(result);
|
||||
}
|
||||
CordovaPlugin callback = this.activityResultCallback;
|
||||
if(callback == null && initCallbackClass != null) {
|
||||
// The application was restarted, but had defined an initial callback
|
||||
// before being shut down.
|
||||
//this.activityResultCallback = appView.pluginManager.getPlugin(initCallbackClass);
|
||||
this.activityResultCallback = appView.getPluginManager().getPlugin(initCallbackClass);
|
||||
callback = this.activityResultCallback;
|
||||
callback = appView.getPluginManager().getPlugin(initCallbackClass);
|
||||
}
|
||||
if(callback != null) {
|
||||
initCallbackClass = null;
|
||||
activityResultCallback = null;
|
||||
|
||||
if (callback != null) {
|
||||
LOG.d(TAG, "We have a callback to send this result to");
|
||||
callback.onActivityResult(requestCode, resultCode, intent);
|
||||
} else {
|
||||
LOG.w(TAG, "Got an activity result, but no plugin was registered to receive it.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setActivityResultCallback(CordovaPlugin plugin) {
|
||||
// Cancel any previously pending activity.
|
||||
if (activityResultCallback != null) {
|
||||
activityResultCallback.onActivityResult(activityResultRequestCode, Activity.RESULT_CANCELED, null);
|
||||
}
|
||||
this.activityResultCallback = plugin;
|
||||
}
|
||||
|
||||
|
51
framework/src/org/apache/cordova/CordovaHttpAuthHandler.java
Normal file
51
framework/src/org/apache/cordova/CordovaHttpAuthHandler.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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.webkit.HttpAuthHandler;
|
||||
|
||||
/**
|
||||
* Specifies interface for HTTP auth handler object which is used to handle auth requests and
|
||||
* specifying user credentials.
|
||||
*/
|
||||
public class CordovaHttpAuthHandler implements ICordovaHttpAuthHandler {
|
||||
|
||||
private final HttpAuthHandler handler;
|
||||
|
||||
public CordovaHttpAuthHandler(HttpAuthHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the WebView to cancel the authentication request.
|
||||
*/
|
||||
public void cancel () {
|
||||
this.handler.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the WebView to proceed with the authentication with the given credentials.
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
*/
|
||||
public void proceed (String username, String password) {
|
||||
this.handler.proceed(username, password);
|
||||
}
|
||||
}
|
@ -196,4 +196,20 @@ public class CordovaPlugin {
|
||||
*/
|
||||
public void onReset() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the system received an HTTP authentication request. Plugin can use
|
||||
* the supplied HttpAuthHandler to process this auth challenge.
|
||||
*
|
||||
* @param view The WebView that is initiating the callback
|
||||
* @param handler The HttpAuthHandler used to set the WebView's response
|
||||
* @param host The host requiring authentication
|
||||
* @param realm The realm for which authentication is required
|
||||
*
|
||||
* @return Returns True if plugin will resolve this auth challenge, otherwise False
|
||||
*
|
||||
*/
|
||||
public boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,6 @@ public interface CordovaWebView {
|
||||
Whitelist getWhitelist();
|
||||
Whitelist getExternalWhitelist();
|
||||
CordovaPreferences getPreferences();
|
||||
|
||||
void onFilePickerResult(Uri uri);
|
||||
|
||||
void setNetworkAvailable(boolean online);
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
/**
|
||||
* Specifies interface for HTTP auth handler object which is used to handle auth requests and
|
||||
* specifying user credentials.
|
||||
*/
|
||||
public interface ICordovaHttpAuthHandler {
|
||||
/**
|
||||
* Instructs the WebView to cancel the authentication request.
|
||||
*/
|
||||
public void cancel ();
|
||||
|
||||
/**
|
||||
* Instructs the WebView to proceed with the authentication with the given credentials.
|
||||
*
|
||||
* @param username The user name
|
||||
* @param password The password
|
||||
*/
|
||||
public void proceed (String username, String password);
|
||||
}
|
@ -209,6 +209,27 @@ public class PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the system received an HTTP authentication request. Plugins can use
|
||||
* the supplied HttpAuthHandler to process this auth challenge.
|
||||
*
|
||||
* @param view The WebView that is initiating the callback
|
||||
* @param handler The HttpAuthHandler used to set the WebView's response
|
||||
* @param host The host requiring authentication
|
||||
* @param realm The realm for which authentication is required
|
||||
*
|
||||
* @return Returns True if there is a plugin which will resolve this auth challenge, otherwise False
|
||||
*
|
||||
*/
|
||||
public boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) {
|
||||
for (CordovaPlugin plugin : this.pluginMap.values()) {
|
||||
if (plugin != null && plugin.onReceivedHttpAuthRequest(view, handler, host, realm)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the activity will start interacting with the user.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user