diff --git a/app/src/main/java/com/owncloud/android/MainApp.java b/app/src/main/java/com/owncloud/android/MainApp.java index 63f23b3f51..243402b7cd 100644 --- a/app/src/main/java/com/owncloud/android/MainApp.java +++ b/app/src/main/java/com/owncloud/android/MainApp.java @@ -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(); diff --git a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java index f54db13671..0a65682937 100644 --- a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -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; } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java b/app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java index d3a5367a27..4170e6141e 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java @@ -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(() -> { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java b/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java index 69a17f2235..1282e96f0d 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java @@ -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); } diff --git a/app/src/main/java/com/owncloud/android/utils/WebViewUtil.kt b/app/src/main/java/com/owncloud/android/utils/WebViewUtil.kt index 93dde6c9d3..deb2f998ad 100644 --- a/app/src/main/java/com/owncloud/android/utils/WebViewUtil.kt +++ b/app/src/main/java/com/owncloud/android/utils/WebViewUtil.kt @@ -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" + } } diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index 6786cf27db..52acffa65d 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -25,6 +25,10 @@ true https://www.nextcloud.com/register + + + -1 + on true