154 lines
6.6 KiB
Java
154 lines
6.6 KiB
Java
|
package app.fedilab.fedilabtube.webview;
|
||
|
|
||
|
|
||
|
import android.annotation.SuppressLint;
|
||
|
import android.content.Context;
|
||
|
import android.content.Intent;
|
||
|
import android.net.Proxy;
|
||
|
import android.util.ArrayMap;
|
||
|
|
||
|
import java.lang.reflect.Constructor;
|
||
|
import java.lang.reflect.Field;
|
||
|
import java.lang.reflect.InvocationTargetException;
|
||
|
import java.lang.reflect.Method;
|
||
|
|
||
|
public class ProxyHelper {
|
||
|
|
||
|
|
||
|
public static void setProxy(Context context, CustomWebview webview, String host, int port, String applicationClassName) {
|
||
|
|
||
|
setProxyKKPlus(context, webview, host, port, applicationClassName);
|
||
|
}
|
||
|
|
||
|
|
||
|
@SuppressWarnings("all")
|
||
|
private static boolean setProxyICS(CustomWebview webview, String host, int port) {
|
||
|
try {
|
||
|
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
|
||
|
Class params[] = new Class[1];
|
||
|
params[0] = Class.forName("android.net.ProxyProperties");
|
||
|
Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
|
||
|
|
||
|
Class wv = Class.forName("android.webkit.WebView");
|
||
|
Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
|
||
|
Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webview);
|
||
|
|
||
|
Class wvc = Class.forName("android.webkit.WebViewCore");
|
||
|
Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
|
||
|
Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);
|
||
|
|
||
|
Class bf = Class.forName("android.webkit.BrowserFrame");
|
||
|
Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
|
||
|
Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
|
||
|
|
||
|
Class ppclass = Class.forName("android.net.ProxyProperties");
|
||
|
Class pparams[] = new Class[3];
|
||
|
pparams[0] = String.class;
|
||
|
pparams[1] = int.class;
|
||
|
pparams[2] = String.class;
|
||
|
Constructor ppcont = ppclass.getConstructor(pparams);
|
||
|
|
||
|
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(host, port, null));
|
||
|
return true;
|
||
|
} catch (Exception ex) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set Proxy for Android 4.1 - 4.3.
|
||
|
*/
|
||
|
@SuppressWarnings("all")
|
||
|
private static boolean setProxyJB(CustomWebview webview, String host, int port) {
|
||
|
|
||
|
try {
|
||
|
Class wvcClass = Class.forName("android.webkit.WebViewClassic");
|
||
|
Class wvParams[] = new Class[1];
|
||
|
wvParams[0] = Class.forName("android.webkit.WebView");
|
||
|
Method fromWebView = wvcClass.getDeclaredMethod("fromWebView", wvParams);
|
||
|
Object webViewClassic = fromWebView.invoke(null, webview);
|
||
|
|
||
|
Class wv = Class.forName("android.webkit.WebViewClassic");
|
||
|
Field mWebViewCoreField = wv.getDeclaredField("mWebViewCore");
|
||
|
Object mWebViewCoreFieldInstance = getFieldValueSafely(mWebViewCoreField, webViewClassic);
|
||
|
|
||
|
Class wvc = Class.forName("android.webkit.WebViewCore");
|
||
|
Field mBrowserFrameField = wvc.getDeclaredField("mBrowserFrame");
|
||
|
Object mBrowserFrame = getFieldValueSafely(mBrowserFrameField, mWebViewCoreFieldInstance);
|
||
|
|
||
|
Class bf = Class.forName("android.webkit.BrowserFrame");
|
||
|
Field sJavaBridgeField = bf.getDeclaredField("sJavaBridge");
|
||
|
Object sJavaBridge = getFieldValueSafely(sJavaBridgeField, mBrowserFrame);
|
||
|
|
||
|
Class ppclass = Class.forName("android.net.ProxyProperties");
|
||
|
Class pparams[] = new Class[3];
|
||
|
pparams[0] = String.class;
|
||
|
pparams[1] = int.class;
|
||
|
pparams[2] = String.class;
|
||
|
Constructor ppcont = ppclass.getConstructor(pparams);
|
||
|
|
||
|
Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge");
|
||
|
Class params[] = new Class[1];
|
||
|
params[0] = Class.forName("android.net.ProxyProperties");
|
||
|
Method updateProxyInstance = jwcjb.getDeclaredMethod("updateProxy", params);
|
||
|
|
||
|
updateProxyInstance.invoke(sJavaBridge, ppcont.newInstance(host, port, null));
|
||
|
} catch (Exception ex) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// from https://stackoverflow.com/questions/19979578/android-webview-set-proxy-programatically-kitkat
|
||
|
@SuppressLint("NewApi")
|
||
|
@SuppressWarnings("all")
|
||
|
private static void setProxyKKPlus(Context appContext, CustomWebview webView, String host, int port, String applicationClassName) {
|
||
|
|
||
|
System.setProperty("http.proxyHost", host);
|
||
|
System.setProperty("http.proxyPort", port + "");
|
||
|
System.setProperty("https.proxyHost", host);
|
||
|
System.setProperty("https.proxyPort", port + "");
|
||
|
try {
|
||
|
Class applictionCls = Class.forName("android.app.Application");
|
||
|
Field loadedApkField = applictionCls.getDeclaredField("mLoadedApk");
|
||
|
loadedApkField.setAccessible(true);
|
||
|
Object loadedApk = loadedApkField.get(appContext);
|
||
|
Class loadedApkCls = Class.forName("android.app.LoadedApk");
|
||
|
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
|
||
|
receiversField.setAccessible(true);
|
||
|
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
|
||
|
for (Object receiverMap : receivers.values()) {
|
||
|
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
|
||
|
Class clazz = rec.getClass();
|
||
|
if (clazz.getName().contains("ProxyChangeListener")) {
|
||
|
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
|
||
|
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
|
||
|
|
||
|
onReceiveMethod.invoke(rec, appContext, intent);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch (ClassNotFoundException e) {
|
||
|
e.printStackTrace();
|
||
|
} catch (NoSuchFieldException e) {
|
||
|
e.printStackTrace();
|
||
|
} catch (IllegalAccessException e) {
|
||
|
e.printStackTrace();
|
||
|
} catch (IllegalArgumentException e) {
|
||
|
e.printStackTrace();
|
||
|
} catch (NoSuchMethodException e) {
|
||
|
e.printStackTrace();
|
||
|
} catch (InvocationTargetException e) {
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static Object getFieldValueSafely(Field field, Object classInstance) throws IllegalArgumentException, IllegalAccessException {
|
||
|
boolean oldAccessibleValue = field.isAccessible();
|
||
|
field.setAccessible(true);
|
||
|
Object result = field.get(classInstance);
|
||
|
field.setAccessible(oldAccessibleValue);
|
||
|
return result;
|
||
|
}
|
||
|
}
|