Optional proxy support

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
This commit is contained in:
tobiasKaminsky 2020-03-02 12:33:48 +01:00 committed by Tobias Kaminsky (Rebase PR Action)
parent 0361a6ddaf
commit 3d1265d6aa
6 changed files with 91 additions and 0 deletions

View file

@ -35,6 +35,7 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
@ -316,6 +317,13 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
try {
OwnCloudClientManagerFactory.setProxyHost(getResources().getString(R.string.proxy_host));
OwnCloudClientManagerFactory.setProxyPort(getResources().getInteger(R.integer.proxy_port));
} catch (Resources.NotFoundException e) {
// no proxy set
}
// initialise thumbnails cache on background thread
new ThumbnailsCacheManager.InitDiskCacheTask().execute();

View file

@ -366,6 +366,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
private void initWebViewLogin(String baseURL, boolean useGenericUserAgent) {
viewThemeUtils.platform.colorCircularProgressBar(accountSetupWebviewBinding.loginWebviewProgressBar, ColorRole.ON_PRIMARY_CONTAINER);
accountSetupWebviewBinding.loginWebview.setVisibility(View.GONE);
new WebViewUtil(this).setProxyKKPlus(accountSetupWebviewBinding.loginWebview);
accountSetupWebviewBinding.loginWebview.getSettings().setAllowFileAccess(false);
accountSetupWebviewBinding.loginWebview.getSettings().setJavaScriptEnabled(true);
@ -402,6 +403,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
url = getResources().getString(R.string.webview_login_url);
}
new WebViewUtil(this).setProxyKKPlus(accountSetupWebviewBinding.loginWebview);
if (url.startsWith(HTTPS_PROTOCOL)) {
strictMode = true;
}

View file

@ -49,6 +49,7 @@ import com.owncloud.android.datamodel.SyncedFolderProvider;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.WebViewUtil;
import javax.inject.Inject;
@ -82,6 +83,11 @@ public abstract class EditorWebView extends ExternalSiteWebView {
this.url = loadedUrl;
if (!url.isEmpty()) {
new WebViewUtil(getApplicationContext()).setProxyKKPlus(this.getWebView());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
this.getWebView().loadUrl(url);
new Handler().postDelayed(() -> {

View file

@ -41,6 +41,7 @@ import com.owncloud.android.databinding.ExternalsiteWebviewBinding;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.ui.NextcloudWebViewClient;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.WebViewUtil;
import java.io.InputStream;
@ -160,6 +161,7 @@ public class ExternalSiteWebView extends FileActivity {
}
});
new WebViewUtil(getApplicationContext()).setProxyKKPlus(getWebView());
getWebView().loadUrl(url);
}

View file

@ -21,12 +21,21 @@
package com.owncloud.android.utils
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Proxy
import android.net.Uri
import android.text.TextUtils
import android.util.ArrayMap
import android.util.Log
import android.webkit.WebView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.owncloud.android.R
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
import java.io.PrintWriter
import java.io.StringWriter
class WebViewUtil(private val context: Context) {
@ -107,4 +116,64 @@ class WebViewUtil(private val context: Context) {
private fun getMinimumSupportedMajorWebViewVersion(): String {
return "118"
}
/**
* From https://stackoverflow.com/a/18453384
*
* @return
*/
@SuppressLint("PrivateApi", "DiscouragedPrivateApi")
fun setProxyKKPlus(webView: WebView) {
val proxyHost = OwnCloudClientManagerFactory.getProxyHost()
val proxyPort = OwnCloudClientManagerFactory.getProxyPort()
if (TextUtils.isEmpty(proxyHost) || proxyPort <= 0) {
return
}
val applicationClassName = "android.app.Application"
Log.d(PROXY_TAG, "Setting proxy with >= 4.4 API.")
val appContext = webView.context.applicationContext
System.setProperty("http.proxyHost", proxyHost)
System.setProperty("http.proxyPort", proxyPort.toString())
System.setProperty("https.proxyHost", proxyHost)
System.setProperty("https.proxyPort", proxyPort.toString())
try {
val applicationClass = Class.forName(applicationClassName)
val loadedApkField = applicationClass.getField("mLoadedApk")
loadedApkField.isAccessible = true
val loadedApk = loadedApkField[appContext]
val loadedApkCls = Class.forName("android.app.LoadedApk")
val receiversField = loadedApkCls.getDeclaredField("mReceivers")
receiversField.isAccessible = true
val receivers = receiversField[loadedApk] as ArrayMap<*, *>
for (receiverMap in receivers.values) {
for (rec in (receiverMap as ArrayMap<*, *>).keys) {
val clazz: Class<*> = rec.javaClass
if (clazz.name.contains("ProxyChangeListener")) {
val onReceiveMethod = clazz.getDeclaredMethod(
"onReceive",
Context::class.java,
Intent::class.java
)
val intent = Intent(Proxy.PROXY_CHANGE_ACTION)
onReceiveMethod.invoke(rec, appContext, intent)
}
}
}
Log.d(PROXY_TAG, "Setting proxy with >= 4.4 API successful!")
} catch (e: Exception) {
val sw = StringWriter()
e.printStackTrace(PrintWriter(sw))
val exceptionAsString = sw.toString()
e.message?.let { Log.v(PROXY_TAG, it) }
Log.v(PROXY_TAG, exceptionAsString)
}
}
companion object {
private const val PROXY_TAG = "PROXY"
}
}

View file

@ -25,6 +25,10 @@
<bool name="show_provider_or_own_installation">true</bool>
<string name="provider_registration_server">https://www.nextcloud.com/register</string>
<!-- specify built in proxy -->
<string name="proxy_host"></string>
<integer name="proxy_port">-1</integer>
<!-- Flags to enable/disable some features -->
<string name="send_files_to_other_apps">on</string>
<bool name="share_via_link_feature">true</bool>