From f19631ad6ab7976fb0cbc324ff70bc26e30d9daf Mon Sep 17 00:00:00 2001 From: Rahul Patel Date: Sun, 22 Oct 2023 14:27:13 +0530 Subject: [PATCH] Add support for proxies - 2/3 --- app/src/main/java/com/aurora/Constants.kt | 1 + .../java/com/aurora/extensions/Threading.kt | 1 + .../com/aurora/store/data/model/ProxyInfo.kt | 9 +++ .../aurora/store/data/network/HttpClient.kt | 27 +++++++- .../store/data/network/IProxyHttpClient.kt | 3 +- .../aurora/store/data/network/OkHttpClient.kt | 32 +++++++-- .../store/data/service/UpdateService.kt | 2 +- .../aurora/store/data/work/UpdateWorker.kt | 4 +- .../java/com/aurora/store/util/CommonUtil.kt | 30 ++++++++ .../java/com/aurora/store/util/Preferences.kt | 3 + .../view/ui/details/AppDetailsFragment.kt | 2 +- .../view/ui/onboarding/OnboardingFragment.kt | 2 + .../view/ui/preferences/NetworkPreference.kt | 68 ++++++++++++++++++- .../store/viewmodel/BaseAndroidViewModel.kt | 2 +- .../aurora/store/viewmodel/MainViewModel.kt | 2 +- .../store/viewmodel/all/BaseAppsViewModel.kt | 2 +- .../viewmodel/all/LibraryAppsViewModel.kt | 2 +- .../store/viewmodel/all/PurchasedViewModel.kt | 2 +- .../store/viewmodel/auth/AuthViewModel.kt | 6 +- .../browse/ExpandedStreamBrowseViewModel.kt | 2 +- .../viewmodel/browse/StreamBrowseViewModel.kt | 2 +- .../category/BaseCategoryViewModel.kt | 2 +- .../viewmodel/details/AppDetailsViewModel.kt | 10 +-- .../details/DetailsClusterViewModel.kt | 2 +- .../viewmodel/details/DevProfileViewModel.kt | 2 +- .../BaseEditorChoiceViewModel.kt | 2 +- .../editorschoice/EditorBrowseViewModel.kt | 2 +- .../homestream/BaseClusterViewModel.kt | 3 +- .../store/viewmodel/review/ReviewViewModel.kt | 2 +- .../store/viewmodel/sale/AppSalesViewModel.kt | 2 +- .../viewmodel/search/SearchResultViewModel.kt | 2 +- .../search/SearchSuggestionViewModel.kt | 2 +- .../SubCategoryClusterViewModel.kt | 2 +- .../viewmodel/topchart/BaseChartViewModel.kt | 2 +- app/src/main/res/values/strings.xml | 9 ++- app/src/main/res/xml/preferences_network.xml | 22 ++++++ 36 files changed, 226 insertions(+), 44 deletions(-) create mode 100644 app/src/main/java/com/aurora/store/data/model/ProxyInfo.kt diff --git a/app/src/main/java/com/aurora/Constants.kt b/app/src/main/java/com/aurora/Constants.kt index ab0e4f89f..5feb8db5c 100644 --- a/app/src/main/java/com/aurora/Constants.kt +++ b/app/src/main/java/com/aurora/Constants.kt @@ -43,6 +43,7 @@ object Constants { const val URL_DISPENSER = "https://auroraoss.com/api/auth" const val PLAY_QUERY_URL = "https://play.google.com/store/search?q=" + const val ANDROID_CONNECTIVITY_URL = "http://connectivitycheck.android.com/generate_204" //ACCOUNTS const val ACCOUNT_SIGNED_IN = "ACCOUNT_SIGNED_IN" diff --git a/app/src/main/java/com/aurora/extensions/Threading.kt b/app/src/main/java/com/aurora/extensions/Threading.kt index d7d94e7ba..038262fdc 100644 --- a/app/src/main/java/com/aurora/extensions/Threading.kt +++ b/app/src/main/java/com/aurora/extensions/Threading.kt @@ -23,6 +23,7 @@ import android.os.Handler import android.os.Looper fun runAsync(action: () -> Unit) = Thread(Runnable(action)).start() +fun runAsyncResult(action: () -> Boolean) = Thread { action() }.apply { start() } fun runOnUiThread(action: () -> Unit) { when { diff --git a/app/src/main/java/com/aurora/store/data/model/ProxyInfo.kt b/app/src/main/java/com/aurora/store/data/model/ProxyInfo.kt new file mode 100644 index 000000000..083c3a519 --- /dev/null +++ b/app/src/main/java/com/aurora/store/data/model/ProxyInfo.kt @@ -0,0 +1,9 @@ +package com.aurora.store.data.model + +data class ProxyInfo( + var protocol: String, + var host: String, + var port: Int, + var proxyUser: String?, + var proxyPassword: String? +) diff --git a/app/src/main/java/com/aurora/store/data/network/HttpClient.kt b/app/src/main/java/com/aurora/store/data/network/HttpClient.kt index 7c15e059c..aa3b49d0b 100644 --- a/app/src/main/java/com/aurora/store/data/network/HttpClient.kt +++ b/app/src/main/java/com/aurora/store/data/network/HttpClient.kt @@ -19,11 +19,32 @@ package com.aurora.store.data.network -import com.aurora.gplayapi.network.IHttpClient +import android.content.Context +import com.aurora.store.data.model.ProxyInfo +import com.aurora.store.util.Log +import com.aurora.store.util.Preferences +import com.google.gson.Gson object HttpClient { + fun getPreferredClient(context: Context): IProxyHttpClient { + val proxyEnabled = Preferences.getBoolean( + context, + Preferences.PREFERENCE_PROXY_ENABLED + ) - fun getPreferredClient(): IHttpClient { - return OkHttpClient + return if (proxyEnabled) { + val proxyInfoString = Preferences.getString(context, Preferences.PREFERENCE_PROXY_INFO) + val proxyInfo = Gson().fromJson(proxyInfoString, ProxyInfo::class.java) + + if (proxyInfo != null) { + OkHttpClient.setProxy(proxyInfo) + } else { + Log.e("Proxy info is unavailable, using default client") + OkHttpClient + } + } else { + Log.i("Proxy is disabled") + OkHttpClient + } } } diff --git a/app/src/main/java/com/aurora/store/data/network/IProxyHttpClient.kt b/app/src/main/java/com/aurora/store/data/network/IProxyHttpClient.kt index 87520405d..32eb56802 100644 --- a/app/src/main/java/com/aurora/store/data/network/IProxyHttpClient.kt +++ b/app/src/main/java/com/aurora/store/data/network/IProxyHttpClient.kt @@ -1,9 +1,10 @@ package com.aurora.store.data.network import com.aurora.gplayapi.network.IHttpClient +import com.aurora.store.data.model.ProxyInfo import java.net.Proxy interface IProxyHttpClient : IHttpClient { @Throws(UnsupportedOperationException::class) - fun setProxy(proxy: Proxy, proxyUser: String?, proxyPassword: String?): IHttpClient + fun setProxy(proxyInfo: ProxyInfo): IHttpClient } \ No newline at end of file diff --git a/app/src/main/java/com/aurora/store/data/network/OkHttpClient.kt b/app/src/main/java/com/aurora/store/data/network/OkHttpClient.kt index f62b21db1..7eac1d13e 100644 --- a/app/src/main/java/com/aurora/store/data/network/OkHttpClient.kt +++ b/app/src/main/java/com/aurora/store/data/network/OkHttpClient.kt @@ -21,6 +21,7 @@ package com.aurora.store.data.network import com.aurora.gplayapi.data.models.PlayResponse import com.aurora.store.BuildConfig +import com.aurora.store.data.model.ProxyInfo import com.aurora.store.util.Log import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -31,6 +32,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType.Companion.toMediaType import okhttp3.RequestBody.Companion.toRequestBody import java.io.IOException +import java.net.InetSocketAddress import java.net.Proxy import java.util.concurrent.TimeUnit @@ -52,13 +54,29 @@ object OkHttpClient : IProxyHttpClient { .followRedirects(true) .followSslRedirects(true) - override fun setProxy( - proxy: Proxy, proxyUser: String?, proxyPassword: String? - ): IProxyHttpClient { - if (proxyUser != null) { - okHttpClientBuilder.proxyAuthenticator { route, response -> - val credential = Credentials.basic(proxyUser, proxyPassword.orEmpty()) - response.request.newBuilder().header("Proxy-Authorization", credential).build() + override fun setProxy(proxyInfo: ProxyInfo): OkHttpClient { + val proxy = Proxy( + if (proxyInfo.protocol == "socks") Proxy.Type.SOCKS else Proxy.Type.HTTP, + InetSocketAddress.createUnresolved( + proxyInfo.host, + proxyInfo.port + ) + ) + + val proxyUser = proxyInfo.proxyUser + val proxyPassword = proxyInfo.proxyPassword + + if (proxyUser != null && proxyPassword != null) { + okHttpClientBuilder.proxyAuthenticator { _, response -> + if (response.request.header("Proxy-Authorization") != null) { + return@proxyAuthenticator null + } + + val credential = Credentials.basic(proxyUser, proxyPassword) + response.request + .newBuilder() + .header("Proxy-Authorization", credential) + .build() } } diff --git a/app/src/main/java/com/aurora/store/data/service/UpdateService.kt b/app/src/main/java/com/aurora/store/data/service/UpdateService.kt index f9766df01..3e95e441b 100644 --- a/app/src/main/java/com/aurora/store/data/service/UpdateService.kt +++ b/app/src/main/java/com/aurora/store/data/service/UpdateService.kt @@ -220,7 +220,7 @@ class UpdateService: LifecycleService() { } EventBus.getDefault().register(this) authData = AuthProvider.with(this).getAuthData() - purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient()) + purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient(this)) downloadManager = DownloadManager.with(this) fetch = downloadManager.fetch fetchListener = object : FetchGroupListener { diff --git a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt index c8a09f185..8bf4615a6 100644 --- a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt @@ -104,7 +104,7 @@ class UpdateWorker(private val appContext: Context, workerParams: WorkerParamete Log.i("Checking for app updates") val appDetailsHelper = AppDetailsHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(appContext)) val isGoogleFilterEnabled = Preferences.getBoolean( appContext, @@ -153,7 +153,7 @@ class UpdateWorker(private val appContext: Context, workerParams: WorkerParamete private fun isValid(authData: AuthData): Boolean { return try { AuthValidator(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(appContext)) .isValid() } catch (e: Exception) { false diff --git a/app/src/main/java/com/aurora/store/util/CommonUtil.kt b/app/src/main/java/com/aurora/store/util/CommonUtil.kt index 26bdd53e6..4d071e06c 100644 --- a/app/src/main/java/com/aurora/store/util/CommonUtil.kt +++ b/app/src/main/java/com/aurora/store/util/CommonUtil.kt @@ -22,6 +22,7 @@ package com.aurora.store.util import android.content.Context import com.aurora.extensions.isSAndAbove import com.aurora.store.R +import com.aurora.store.data.model.ProxyInfo import java.text.DecimalFormat import java.util.Locale import kotlin.math.ln @@ -82,9 +83,11 @@ object CommonUtil { hours > 0 -> { context.getString(R.string.download_eta_hrs, hours, minutes, seconds) } + minutes > 0 -> { context.getString(R.string.download_eta_min, minutes, seconds) } + else -> { context.getString(R.string.download_eta_sec, seconds) } @@ -126,9 +129,11 @@ object CommonUtil { mb >= 1 -> { context.getString(R.string.download_speed_mb, decimalFormat.format(mb)) } + kb >= 1 -> { context.getString(R.string.download_speed_kb, decimalFormat.format(kb)) } + else -> { context.getString(R.string.download_speed_bytes, downloadedBytesPerSecond) } @@ -179,4 +184,29 @@ object CommonUtil { else -> if (isSAndAbove()) R.style.Accent00 else R.style.Accent01 } } + + fun parseProxyUrl(proxyUrl: String): ProxyInfo? { + val pattern = """^(https?|socks)://(?:([^\s:@]+):([^\s:@]+)@)?([^\s:@]+):(\d+)$""".toRegex() + val match = pattern.find(proxyUrl) + + return when { + match != null -> { + val protocol = match.groupValues[1].toUpperCase() + val username = match.groupValues[2] + val password = match.groupValues[3] + val url = match.groupValues[4] + val port = match.groupValues[5] + + ProxyInfo( + protocol, + url, + port.toInt(), + username, + password + ) + } + + else -> null + } + } } diff --git a/app/src/main/java/com/aurora/store/util/Preferences.kt b/app/src/main/java/com/aurora/store/util/Preferences.kt index 752f25510..9a9d50b00 100644 --- a/app/src/main/java/com/aurora/store/util/Preferences.kt +++ b/app/src/main/java/com/aurora/store/util/Preferences.kt @@ -56,6 +56,9 @@ object Preferences { const val PREFERENCE_TOS_READ = "PREFERENCE_TOS_READ" const val PREFERENCE_INSECURE_ANONYMOUS = "PREFERENCE_INSECURE_ANONYMOUS" + const val PREFERENCE_PROXY_URL = "PREFERENCE_PROXY_URL" + const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO" + const val PREFERENCE_PROXY_ENABLED = "PREFERENCE_PROXY_ENABLED" const val PREFERENCE_UPDATES_EXTENDED = "PREFERENCE_UPDATES_EXTENDED" const val PREFERENCE_UPDATES_CHECK = "PREFERENCE_UPDATES_CHECK" diff --git a/app/src/main/java/com/aurora/store/view/ui/details/AppDetailsFragment.kt b/app/src/main/java/com/aurora/store/view/ui/details/AppDetailsFragment.kt index 464c6bf4e..562feb3e8 100644 --- a/app/src/main/java/com/aurora/store/view/ui/details/AppDetailsFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/details/AppDetailsFragment.kt @@ -1081,7 +1081,7 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) { } private fun inflateAppPrivacy(app: App) { - viewModel.fetchAppReport(app.packageName) + viewModel.fetchAppReport(requireContext(), app.packageName) } private fun inflateAppDevInfo(B: LayoutDetailsDevBinding, app: App) { diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt index e1839df0d..77b925020 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt @@ -48,6 +48,7 @@ import com.aurora.store.util.Preferences.PREFERENCE_FOR_YOU import com.aurora.store.util.Preferences.PREFERENCE_INSECURE_ANONYMOUS import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID import com.aurora.store.util.Preferences.PREFERENCE_INTRO +import com.aurora.store.util.Preferences.PREFERENCE_PROXY_ENABLED import com.aurora.store.util.Preferences.PREFERENCE_SIMILAR import com.aurora.store.util.Preferences.PREFERENCE_THEME_ACCENT import com.aurora.store.util.Preferences.PREFERENCE_THEME_TYPE @@ -165,6 +166,7 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) { /*Network*/ save(PREFERENCE_INSECURE_ANONYMOUS, false) + save(PREFERENCE_PROXY_ENABLED, false) /*Customization*/ save(PREFERENCE_THEME_TYPE, 0) diff --git a/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt b/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt index 1db0ce8cc..d3332e397 100644 --- a/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt +++ b/app/src/main/java/com/aurora/store/view/ui/preferences/NetworkPreference.kt @@ -25,16 +25,82 @@ import androidx.appcompat.widget.Toolbar import androidx.navigation.fragment.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import com.aurora.Constants +import com.aurora.extensions.runAsync import com.aurora.extensions.runOnUiThread import com.aurora.extensions.toast import com.aurora.store.R +import com.aurora.store.data.network.HttpClient +import com.aurora.store.util.CommonUtil import com.aurora.store.util.Preferences +import com.aurora.store.util.save +import com.google.gson.Gson class NetworkPreference : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences_network, rootKey) + val proxyUrl = Preferences.getString(requireContext(), Preferences.PREFERENCE_PROXY_URL, "") + val proxyInfo = + Preferences.getString(requireContext(), Preferences.PREFERENCE_PROXY_INFO, "{}") + + val preferenceProxyUrl: Preference? = findPreference(Preferences.PREFERENCE_PROXY_URL) + preferenceProxyUrl?.summary = proxyUrl + + preferenceProxyUrl?.let { + it.onPreferenceChangeListener = + Preference.OnPreferenceChangeListener { preference, newValue -> + val newProxyUrl = newValue.toString() + val newProxyInfo = CommonUtil.parseProxyUrl(newProxyUrl) + + if (newProxyInfo == null) { + runOnUiThread { + requireContext().toast(getString(R.string.toast_proxy_invalid)) + } + false + } else { + runAsync { + kotlin.runCatching { + val result = HttpClient + .getPreferredClient(requireContext()) + .setProxy(newProxyInfo) + .get( + Constants.ANDROID_CONNECTIVITY_URL, + mapOf() + ) + + runOnUiThread { + if (result.code == 204) { + requireContext().toast(getString(R.string.toast_proxy_success)) + save(Preferences.PREFERENCE_PROXY_URL, newProxyUrl) + save( + Preferences.PREFERENCE_PROXY_INFO, + Gson().toJson(newProxyInfo) + ) + + preference.summary = newProxyUrl + } else { + throw Exception("Failed to set proxy") + } + } + }.onFailure { + runOnUiThread { + requireContext().toast(getText(R.string.toast_proxy_failed)) + save(Preferences.PREFERENCE_PROXY_URL, proxyUrl) + save( + Preferences.PREFERENCE_PROXY_INFO, + proxyInfo + ) + } + } + } + + true + } + } + } + val insecureAnonymous: Preference? = findPreference(Preferences.PREFERENCE_INSECURE_ANONYMOUS) @@ -56,4 +122,4 @@ class NetworkPreference : PreferenceFragmentCompat() { setNavigationOnClickListener { findNavController().navigateUp() } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt index 35a5c5bd0..6e84c9b8c 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt @@ -32,7 +32,7 @@ import java.lang.reflect.Modifier abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel(application) { - val responseCode = HttpClient.getPreferredClient().responseCode + val responseCode = HttpClient.getPreferredClient(application).responseCode protected val gson: Gson = GsonBuilder() .excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC) diff --git a/app/src/main/java/com/aurora/store/viewmodel/MainViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/MainViewModel.kt index 8e0358986..6009b1cc8 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/MainViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/MainViewModel.kt @@ -29,7 +29,7 @@ class MainViewModel : ViewModel() { try { val gson: Gson = GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create() - val response = HttpClient.getPreferredClient().get(Constants.UPDATE_URL, mapOf()) + val response = HttpClient.getPreferredClient(context).get(Constants.UPDATE_URL, mapOf()) val selfUpdate = gson.fromJson(String(response.responseBytes), SelfUpdate::class.java) diff --git a/app/src/main/java/com/aurora/store/viewmodel/all/BaseAppsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/all/BaseAppsViewModel.kt index bed6c9acc..a73161647 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/all/BaseAppsViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/all/BaseAppsViewModel.kt @@ -37,7 +37,7 @@ abstract class BaseAppsViewModel(application: Application) : BaseAndroidViewMode .getAuthData() private val appDetailsHelper = AppDetailsHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) var blacklistProvider = BlacklistProvider .with(application) diff --git a/app/src/main/java/com/aurora/store/viewmodel/all/LibraryAppsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/all/LibraryAppsViewModel.kt index d81f66bd3..75c197e19 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/all/LibraryAppsViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/all/LibraryAppsViewModel.kt @@ -37,7 +37,7 @@ class LibraryAppsViewModel(application: Application) : BaseAndroidViewModel(appl private val authData: AuthData = AuthProvider.with(application).getAuthData() private val clusterHelper: ClusterHelper = - ClusterHelper(authData).using(HttpClient.getPreferredClient()) + ClusterHelper(authData).using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() var streamCluster: StreamCluster = StreamCluster() diff --git a/app/src/main/java/com/aurora/store/viewmodel/all/PurchasedViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/all/PurchasedViewModel.kt index fc630b21d..10029e9f9 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/all/PurchasedViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/all/PurchasedViewModel.kt @@ -41,7 +41,7 @@ class PurchasedViewModel(application: Application) : BaseAndroidViewModel(applic private val authData = AuthProvider.with(application).getAuthData() - private val purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient()) + private val purchaseHelper = PurchaseHelper(authData).using(HttpClient.getPreferredClient(application)) private var appList: MutableList = mutableListOf() diff --git a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt index 7b09c4f64..f60adbaee 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt @@ -121,7 +121,7 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application properties = spoofProvider.getSpoofDeviceProperties() val playResponse = HttpClient - .getPreferredClient() + .getPreferredClient(getApplication()) .postAuth( Constants.URL_DISPENSER, gson.toJson(properties).toByteArray() @@ -157,7 +157,7 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application properties = spoofProvider.getSpoofDeviceProperties() val playResponse = HttpClient - .getPreferredClient() + .getPreferredClient(getApplication()) .getAuth( Constants.URL_DISPENSER ) @@ -275,7 +275,7 @@ class AuthViewModel(application: Application) : BaseAndroidViewModel(application private fun isValid(authData: AuthData): Boolean { return try { AuthValidator(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(getApplication())) .isValid() } catch (e: Exception) { false diff --git a/app/src/main/java/com/aurora/store/viewmodel/browse/ExpandedStreamBrowseViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/browse/ExpandedStreamBrowseViewModel.kt index e3a022fe6..1f9dbc1ee 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/browse/ExpandedStreamBrowseViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/browse/ExpandedStreamBrowseViewModel.kt @@ -38,7 +38,7 @@ class ExpandedStreamBrowseViewModel(application: Application) : BaseAndroidViewM private val authData: AuthData = AuthProvider.with(application).getAuthData() private val streamHelper: ExpandedBrowseHelper = ExpandedBrowseHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() var streamCluster: StreamCluster = StreamCluster() diff --git a/app/src/main/java/com/aurora/store/viewmodel/browse/StreamBrowseViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/browse/StreamBrowseViewModel.kt index a19d0a853..a54dcb67f 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/browse/StreamBrowseViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/browse/StreamBrowseViewModel.kt @@ -38,7 +38,7 @@ class StreamBrowseViewModel(application: Application) : BaseAndroidViewModel(app private val authData: AuthData = AuthProvider.with(application).getAuthData() private val streamHelper: StreamHelper = StreamHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() var streamCluster: StreamCluster = StreamCluster() diff --git a/app/src/main/java/com/aurora/store/viewmodel/category/BaseCategoryViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/category/BaseCategoryViewModel.kt index d842f44f8..a6c295327 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/category/BaseCategoryViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/category/BaseCategoryViewModel.kt @@ -39,7 +39,7 @@ abstract class BaseCategoryViewModel(application: Application) : BaseAndroidView .getAuthData() private val streamHelper: CategoryHelper = CategoryHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData> = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt index 74951c9da..77649518c 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt @@ -49,7 +49,7 @@ class AppDetailsViewModel : ViewModel() { try { val authData = AuthProvider.with(context).getAuthData() _app.emit( - AppDetailsHelper(authData).using(HttpClient.getPreferredClient()) + AppDetailsHelper(authData).using(HttpClient.getPreferredClient(context)) .getAppByPackageName(packageName) ) } catch (exception: Exception) { @@ -63,7 +63,7 @@ class AppDetailsViewModel : ViewModel() { viewModelScope.launch(Dispatchers.IO) { try { val authData = AuthProvider.with(context).getAuthData() - _reviews.emit(ReviewsHelper(authData).using(HttpClient.getPreferredClient()) + _reviews.emit(ReviewsHelper(authData).using(HttpClient.getPreferredClient(context)) .getReviewSummary(packageName)) } catch (exception: Exception) { Log.e(TAG, "Failed to fetch app reviews", exception) @@ -77,7 +77,7 @@ class AppDetailsViewModel : ViewModel() { try { val authData = AuthProvider.with(context).getAuthData() _userReview.emit(ReviewsHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(context)) .addOrEditReview( packageName, review.title, @@ -93,7 +93,7 @@ class AppDetailsViewModel : ViewModel() { } - fun fetchAppReport(packageName: String) { + fun fetchAppReport(context: Context,packageName: String) { viewModelScope.launch(Dispatchers.IO) { try { val headers: MutableMap = mutableMapOf() @@ -102,7 +102,7 @@ class AppDetailsViewModel : ViewModel() { headers["Authorization"] = exodusApiKey val url = exodusBaseUrl + packageName - val playResponse = HttpClient.getPreferredClient().get(url, headers) + val playResponse = HttpClient.getPreferredClient(context).get(url, headers) _report.emit(parseResponse(String(playResponse.responseBytes), packageName)[0]) } catch (exception: Exception) { diff --git a/app/src/main/java/com/aurora/store/viewmodel/details/DetailsClusterViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/details/DetailsClusterViewModel.kt index 3684208ce..7d6c36b85 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/details/DetailsClusterViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/details/DetailsClusterViewModel.kt @@ -40,7 +40,7 @@ import kotlinx.coroutines.supervisorScope class DetailsClusterViewModel(application: Application) : BaseAndroidViewModel(application) { private var authData: AuthData = AuthProvider.with(application).getAuthData() - private var appDetailsHelper = AppDetailsHelper(authData).using(HttpClient.getPreferredClient()) + private var appDetailsHelper = AppDetailsHelper(authData).using(HttpClient.getPreferredClient(application)) private var streamHelper = StreamHelper(authData) val liveData: MutableLiveData = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/details/DevProfileViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/details/DevProfileViewModel.kt index 98912ebf7..918ed86ee 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/details/DevProfileViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/details/DevProfileViewModel.kt @@ -41,7 +41,7 @@ import kotlinx.coroutines.supervisorScope class DevProfileViewModel(application: Application) : BaseAndroidViewModel(application) { private var authData: AuthData = AuthProvider.with(application).getAuthData() - private var appDetailsHelper = AppDetailsHelper(authData).using(HttpClient.getPreferredClient()) + private var appDetailsHelper = AppDetailsHelper(authData).using(HttpClient.getPreferredClient(application)) private var streamHelper = StreamHelper(authData) val liveData: MutableLiveData = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/editorschoice/BaseEditorChoiceViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/editorschoice/BaseEditorChoiceViewModel.kt index 48c8582c4..786a924af 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/editorschoice/BaseEditorChoiceViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/editorschoice/BaseEditorChoiceViewModel.kt @@ -40,7 +40,7 @@ open class BaseEditorChoiceViewModel(application: Application) : BaseAndroidView .getAuthData() private val streamHelper: StreamHelper = StreamHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) lateinit var category: StreamHelper.Category diff --git a/app/src/main/java/com/aurora/store/viewmodel/editorschoice/EditorBrowseViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/editorschoice/EditorBrowseViewModel.kt index 6b8354fca..157de9bd4 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/editorschoice/EditorBrowseViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/editorschoice/EditorBrowseViewModel.kt @@ -37,7 +37,7 @@ class EditorBrowseViewModel(application: Application) : BaseAndroidViewModel(app private val authData: AuthData = AuthProvider.with(application).getAuthData() private val streamHelper: StreamHelper = StreamHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData> = MutableLiveData() val appList: MutableList = mutableListOf() diff --git a/app/src/main/java/com/aurora/store/viewmodel/homestream/BaseClusterViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/homestream/BaseClusterViewModel.kt index 8dc3c6064..ee9aecd67 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/homestream/BaseClusterViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/homestream/BaseClusterViewModel.kt @@ -39,8 +39,9 @@ import kotlinx.coroutines.supervisorScope abstract class BaseClusterViewModel(application: Application) : BaseAndroidViewModel(application) { var authData: AuthData = AuthProvider.with(application).getAuthData() + var streamHelper: StreamHelper = StreamHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() var streamBundle: StreamBundle = StreamBundle() diff --git a/app/src/main/java/com/aurora/store/viewmodel/review/ReviewViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/review/ReviewViewModel.kt index 3c8a37f50..7af1c867a 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/review/ReviewViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/review/ReviewViewModel.kt @@ -41,7 +41,7 @@ class ReviewViewModel(application: Application) : BaseAndroidViewModel(applicati .getAuthData() var reviewsHelper: ReviewsHelper = ReviewsHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/sale/AppSalesViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/sale/AppSalesViewModel.kt index bb8ae07f8..3620fe083 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/sale/AppSalesViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/sale/AppSalesViewModel.kt @@ -38,7 +38,7 @@ class AppSalesViewModel(application: Application) : BaseAndroidViewModel(applica private val authData: AuthData = AuthProvider.with(application).getAuthData() private val appSalesHelper: AppSalesHelper = - AppSalesHelper(authData).using(HttpClient.getPreferredClient()) + AppSalesHelper(authData).using(HttpClient.getPreferredClient(application)) private var page: Int = 0 private val appList: MutableList = mutableListOf() diff --git a/app/src/main/java/com/aurora/store/viewmodel/search/SearchResultViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/search/SearchResultViewModel.kt index e6c034864..176473af6 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/search/SearchResultViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/search/SearchResultViewModel.kt @@ -45,7 +45,7 @@ class SearchResultViewModel(application: Application) : BaseAndroidViewModel(app private val webSearchHelper: WebSearchHelper = WebSearchHelper(authData) private val searchHelper: SearchHelper = SearchHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/search/SearchSuggestionViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/search/SearchSuggestionViewModel.kt index 576e4a9b3..7035f4bc9 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/search/SearchSuggestionViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/search/SearchSuggestionViewModel.kt @@ -40,7 +40,7 @@ class SearchSuggestionViewModel(application: Application) : AndroidViewModel(app private val webSearchHelper: WebSearchHelper = WebSearchHelper(authData) private val searchHelper: SearchHelper = SearchHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveSearchSuggestions: MutableLiveData> = MutableLiveData() diff --git a/app/src/main/java/com/aurora/store/viewmodel/subcategory/SubCategoryClusterViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/subcategory/SubCategoryClusterViewModel.kt index 57be79a8a..96e90d6da 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/subcategory/SubCategoryClusterViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/subcategory/SubCategoryClusterViewModel.kt @@ -40,7 +40,7 @@ class SubCategoryClusterViewModel(application: Application) : BaseAndroidViewMod var authData: AuthData = AuthProvider.with(application).getAuthData() var categoryHelper: CategoryHelper = CategoryHelper(authData) - .using(HttpClient.getPreferredClient()) + .using(HttpClient.getPreferredClient(application)) val liveData: MutableLiveData = MutableLiveData() var streamBundle: StreamBundle = StreamBundle() diff --git a/app/src/main/java/com/aurora/store/viewmodel/topchart/BaseChartViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/topchart/BaseChartViewModel.kt index 0542cf7aa..7d9feb98c 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/topchart/BaseChartViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/topchart/BaseChartViewModel.kt @@ -37,7 +37,7 @@ abstract class BaseChartViewModel(application: Application) : BaseAndroidViewMod private val authData: AuthData = AuthProvider.with(application).getAuthData() private val topChartsHelper: TopChartsHelper = - TopChartsHelper(authData).using(HttpClient.getPreferredClient()) + TopChartsHelper(authData).using(HttpClient.getPreferredClient(application)) lateinit var type: TopChartsHelper.Type lateinit var chart: TopChartsHelper.Chart diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 379264183..912cd5ef9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -240,6 +240,10 @@ "Select the target profile to install apps to. Only works with the root installation method" "Installation profiles (Experimental)" "Networking" + Proxy + "Enable proxy" + "Allow all traffic from app to go through the proxy" + "Proxy URL" "Accent" "Black" "Dark" @@ -326,7 +330,10 @@ Device config exported Could not export device config Device config imported - Could not import device config + "Could not import device config" + "Invalid proxy URL, check format!" + "Proxy set successfully" + "Failed to set proxy" App background download service Background app download Enables background app download diff --git a/app/src/main/res/xml/preferences_network.xml b/app/src/main/res/xml/preferences_network.xml index 68afb204a..5a2aa8352 100644 --- a/app/src/main/res/xml/preferences_network.xml +++ b/app/src/main/res/xml/preferences_network.xml @@ -19,6 +19,28 @@ + + + + + + +