Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(android): remove "WebViewClient.jar" from SDK #12708

Merged
merged 3 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file removed android/modules/ui/lib/WebViewClient.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,24 @@
import ti.modules.titanium.media.TiVideoActivity;
import ti.modules.titanium.ui.WebViewProxy;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.AsyncTask;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
import android.webkit.ClientCertRequest;
import android.webkit.ClientCertRequestHandler;
import android.webkit.HttpAuthHandler;
import android.webkit.MimeTypeMap;
import android.webkit.SslErrorHandler;
import android.webkit.URLUtil;
import android.webkit.WebView;
import android.webkit.WebViewClientClassicExt;
import android.webkit.WebViewClient;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;

public class TiWebViewClient extends WebViewClientClassicExt
public class TiWebViewClient extends WebViewClient
{
private static final String TAG = "TiWVC";

Expand Down Expand Up @@ -233,102 +228,37 @@ public void setBasicAuthentication(String username, String password)
this.password = password;
}

/*
* ClientCertRequest wrapper for compatibility with both ClientCertRequest and ClientCertRequestHandler
*/
private static class ClientCertRequestCompat
@Override
public void onReceivedClientCertRequest(WebView view, final ClientCertRequest request)
{
private ClientCertRequest clientCertRequest;
private ClientCertRequestHandler clientCertRequestHandler;

ClientCertRequestCompat(Object request)
{
if (request instanceof ClientCertRequest) {
clientCertRequest = (ClientCertRequest) request;
} else if (request instanceof ClientCertRequestHandler) {
clientCertRequestHandler = (ClientCertRequestHandler) request;
}
}

@SuppressLint("NewApi")
public void cancel()
{
if (clientCertRequest != null) {
clientCertRequest.cancel();
} else if (clientCertRequestHandler != null) {
clientCertRequestHandler.cancel();
}
}

@SuppressLint("NewApi")
public void ignore()
{
if (clientCertRequest != null) {
clientCertRequest.ignore();
} else if (clientCertRequestHandler != null) {
clientCertRequestHandler.ignore();
}
}

@SuppressLint("NewApi")
public void proceed(PrivateKey privateKey, X509Certificate[] x509Certificates)
{
if (clientCertRequest != null) {
clientCertRequest.proceed(privateKey, x509Certificates);
} else if (clientCertRequestHandler != null) {
clientCertRequestHandler.proceed(privateKey, x509Certificates);
}
// Validate.
if (request == null) {
return;
}
}

@TargetApi(16)
private void handleClientCertRequest(final Object requestObj, final String host, final int port)
{
// Fetch top-most activity.
final Activity activity = TiApplication.getAppRootOrCurrentActivity();
final ClientCertRequestCompat request = new ClientCertRequestCompat(requestObj);
if (activity == null) {
request.ignore();
return;
}

KeyChain.choosePrivateKeyAlias(activity, new KeyChainAliasCallback() {
@Override
public void alias(final String alias)
{
final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... args)
{
try {
PrivateKey privateKey = KeyChain.getPrivateKey(activity, alias);
X509Certificate[] certificateChain = KeyChain.getCertificateChain(activity, alias);
request.proceed(privateKey, certificateChain);
} catch (Exception e) {
request.ignore();
}
return null;
}
}.execute();
// Ask end-user to select an installed certificate.
KeyChain.choosePrivateKeyAlias(activity, (String alias) -> {
if (alias == null) {
request.ignore();
return;
}
}, null, null, host, port, null);
}

@TargetApi(21)
@Override
public void onReceivedClientCertRequest(WebView view, ClientCertRequest request)
{
handleClientCertRequest(request, request.getHost(), request.getPort());
}

/*
* this is a "hidden" callback implemented on API 16 - 18 for handling certificate requests
* note: Android 4.4 prevents this from being called, stating "Client certificates not supported in WebView"
*/
@TargetApi(16)
@Override
public void onReceivedClientCertRequest(WebView view, ClientCertRequestHandler handler, String host_and_port)
{
String[] hostPort = host_and_port.split(":");
String host = hostPort[0];
int port = Integer.parseInt(hostPort[1]);

handleClientCertRequest(handler, host, port);
new Thread(() -> {
try {
PrivateKey privateKey = KeyChain.getPrivateKey(activity, alias);
X509Certificate[] certificateChain = KeyChain.getCertificateChain(activity, alias);
request.proceed(privateKey, certificateChain);
} catch (Exception e) {
request.ignore();
}
}).start();
}, null, null, request.getHost(), request.getPort(), null);
}

@Override
Expand Down
1 change: 0 additions & 1 deletion android/titanium/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ dependencies {

// Reference all local JAR file dependencies.
implementation fileTree(dir: 'lib', include: ['*.jar'])
implementation fileTree(dir: "${projectDir}/../modules/ui/lib", include: ['*.jar'])
}

// This block is used when we do a "gradlew :titanium:publish", which is invoked by our "node scons package" tool.
Expand Down