Skip to content

Commit

Permalink
refactor(android): remove WebViewClient.jar from SDK
Browse files Browse the repository at this point in the history
Fixes TIMOB-28241
  • Loading branch information
jquick-axway authored and ewanharris committed Jun 15, 2021
1 parent be8f31e commit 502f17e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 98 deletions.
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

0 comments on commit 502f17e

Please sign in to comment.