feat(human-verification, network)!: Provide a shared (singleton) instance of OkHttpClient.

The provided `OkHttpClient` instance is not customized in any way,
and can be used to contruct your own HTTP clients (`OkHttpClient.newBuilder`).

BREAKING-CHANGE: `ApiManagerFactory` takes `OkHttpClient` as a constructor argument. To inject, use `@SharedOkHttpClient` annotation.
This commit is contained in:
Mateusz Armatys
2022-07-25 19:55:43 +02:00
parent 454bf42593
commit b4e2f86076
12 changed files with 69 additions and 13 deletions
@@ -36,6 +36,7 @@ import me.proton.core.network.data.ApiManagerFactory
import me.proton.core.network.data.ProtonCookieStore
import me.proton.core.network.data.client.ClientIdProviderImpl
import me.proton.core.network.data.client.ExtraHeaderProviderImpl
import me.proton.core.network.data.di.SharedOkHttpClient
import me.proton.core.network.domain.ApiClient
import me.proton.core.network.domain.NetworkManager
import me.proton.core.network.domain.NetworkPrefs
@@ -92,7 +93,8 @@ class NetworkModule {
@BaseApiUrl baseApiUrl: String,
@DohProviderUrls dohProviderUrls: Array<String>,
@CertificatePins certificatePins: Array<String>,
@AlternativeApiPins alternativeApiPins: List<String>
@AlternativeApiPins alternativeApiPins: List<String>,
@SharedOkHttpClient okHttpClient: OkHttpClient
): ApiManagerFactory {
return ApiManagerFactory(
baseApiUrl,
@@ -119,7 +121,8 @@ class NetworkModule {
extraHeaderProvider = extraHeaderProvider,
clientVersionValidator = clientVersionValidator,
dohAlternativesListener = dohAlternativesListener,
dohProviderUrls = dohProviderUrls
dohProviderUrls = dohProviderUrls,
okHttpClient = okHttpClient
)
}
}
@@ -166,9 +169,6 @@ class NetworkCallbacksModule {
context.pgpCrypto.updateTime(epochSeconds)
}
}
@Provides
fun provideOkHttpClient(): OkHttpClient = OkHttpClient()
}
@Module
@@ -31,6 +31,7 @@ dependencies {
project(Module.networkDomain),
project(Module.cryptoCommon),
project(Module.networkData),
project(Module.networkDagger),
`room-ktx`,
)
@@ -39,6 +39,7 @@ import me.proton.core.humanverification.domain.utils.NetworkRequestOverrider
import me.proton.core.humanverification.presentation.HumanVerificationOrchestrator
import me.proton.core.humanverification.presentation.utils.HumanVerificationVersion
import me.proton.core.network.data.ApiProvider
import me.proton.core.network.data.di.SharedOkHttpClient
import me.proton.core.network.domain.humanverification.HumanVerificationListener
import me.proton.core.network.domain.humanverification.HumanVerificationProvider
import okhttp3.OkHttpClient
@@ -56,7 +57,7 @@ public object CoreHumanVerificationModule {
@Provides
public fun provideNetworkRequestOverrider(
okHttpClient: OkHttpClient,
@SharedOkHttpClient okHttpClient: OkHttpClient,
): NetworkRequestOverrider =
NetworkRequestOverriderImpl(okHttpClient)
+8
View File
@@ -49,3 +49,11 @@ public final class me/proton/core/network/dagger/CoreNetworkModule_ProvideNetwor
public static fun provideNetworkPrefs (Lme/proton/core/network/dagger/CoreNetworkModule;Landroid/content/Context;)Lme/proton/core/network/domain/NetworkPrefs;
}
public final class me/proton/core/network/dagger/CoreNetworkModule_ProvideOkHttpClientFactory : dagger/internal/Factory {
public fun <init> (Lme/proton/core/network/dagger/CoreNetworkModule;)V
public static fun create (Lme/proton/core/network/dagger/CoreNetworkModule;)Lme/proton/core/network/dagger/CoreNetworkModule_ProvideOkHttpClientFactory;
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Lokhttp3/OkHttpClient;
public static fun provideOkHttpClient (Lme/proton/core/network/dagger/CoreNetworkModule;)Lokhttp3/OkHttpClient;
}
@@ -32,9 +32,12 @@ import me.proton.core.network.data.ProtonCookieStore
import me.proton.core.network.data.client.ClientVersionValidatorImpl
import me.proton.core.network.data.cookie.DiskCookieStorage
import me.proton.core.network.data.cookie.MemoryCookieStorage
import me.proton.core.network.data.di.SharedOkHttpClient
import me.proton.core.network.domain.NetworkManager
import me.proton.core.network.domain.client.ClientVersionValidator
import me.proton.core.network.domain.session.SessionProvider
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import javax.inject.Singleton
@Module
@@ -64,4 +67,9 @@ internal class CoreNetworkModule {
@Singleton
fun provideApiProvider(apiManagerFactory: ApiManagerFactory, sessionProvider: SessionProvider): ApiProvider =
ApiProvider(apiManagerFactory, sessionProvider)
@Provides
@Singleton
@SharedOkHttpClient
fun provideOkHttpClient(): OkHttpClient = OkHttpClient()
}
+5 -2
View File
@@ -1,6 +1,6 @@
public final class me/proton/core/network/data/ApiManagerFactory {
public fun <init> (Ljava/lang/String;Lme/proton/core/network/domain/ApiClient;Lme/proton/core/network/domain/client/ClientIdProvider;Lme/proton/core/network/domain/server/ServerTimeListener;Lme/proton/core/network/domain/NetworkManager;Lme/proton/core/network/domain/NetworkPrefs;Lme/proton/core/network/domain/session/SessionProvider;Lme/proton/core/network/domain/session/SessionListener;Lme/proton/core/network/domain/humanverification/HumanVerificationProvider;Lme/proton/core/network/domain/humanverification/HumanVerificationListener;Lme/proton/core/network/domain/scopes/MissingScopeListener;Lme/proton/core/network/data/ProtonCookieStore;Lkotlinx/coroutines/CoroutineScope;[Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function0;Lme/proton/core/network/domain/client/ExtraHeaderProvider;Lme/proton/core/network/domain/client/ClientVersionValidator;Lme/proton/core/network/domain/serverconnection/DohAlternativesListener;[Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Lme/proton/core/network/domain/ApiClient;Lme/proton/core/network/domain/client/ClientIdProvider;Lme/proton/core/network/domain/server/ServerTimeListener;Lme/proton/core/network/domain/NetworkManager;Lme/proton/core/network/domain/NetworkPrefs;Lme/proton/core/network/domain/session/SessionProvider;Lme/proton/core/network/domain/session/SessionListener;Lme/proton/core/network/domain/humanverification/HumanVerificationProvider;Lme/proton/core/network/domain/humanverification/HumanVerificationListener;Lme/proton/core/network/domain/scopes/MissingScopeListener;Lme/proton/core/network/data/ProtonCookieStore;Lkotlinx/coroutines/CoroutineScope;[Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function0;Lme/proton/core/network/domain/client/ExtraHeaderProvider;Lme/proton/core/network/domain/client/ClientVersionValidator;Lme/proton/core/network/domain/serverconnection/DohAlternativesListener;[Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Lme/proton/core/network/domain/ApiClient;Lme/proton/core/network/domain/client/ClientIdProvider;Lme/proton/core/network/domain/server/ServerTimeListener;Lme/proton/core/network/domain/NetworkManager;Lme/proton/core/network/domain/NetworkPrefs;Lme/proton/core/network/domain/session/SessionProvider;Lme/proton/core/network/domain/session/SessionListener;Lme/proton/core/network/domain/humanverification/HumanVerificationProvider;Lme/proton/core/network/domain/humanverification/HumanVerificationListener;Lme/proton/core/network/domain/scopes/MissingScopeListener;Lme/proton/core/network/data/ProtonCookieStore;Lkotlinx/coroutines/CoroutineScope;[Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function0;Lme/proton/core/network/domain/client/ExtraHeaderProvider;Lme/proton/core/network/domain/client/ClientVersionValidator;Lme/proton/core/network/domain/serverconnection/DohAlternativesListener;[Ljava/lang/String;Lokhttp3/OkHttpClient;)V
public synthetic fun <init> (Ljava/lang/String;Lme/proton/core/network/domain/ApiClient;Lme/proton/core/network/domain/client/ClientIdProvider;Lme/proton/core/network/domain/server/ServerTimeListener;Lme/proton/core/network/domain/NetworkManager;Lme/proton/core/network/domain/NetworkPrefs;Lme/proton/core/network/domain/session/SessionProvider;Lme/proton/core/network/domain/session/SessionListener;Lme/proton/core/network/domain/humanverification/HumanVerificationProvider;Lme/proton/core/network/domain/humanverification/HumanVerificationListener;Lme/proton/core/network/domain/scopes/MissingScopeListener;Lme/proton/core/network/data/ProtonCookieStore;Lkotlinx/coroutines/CoroutineScope;[Ljava/lang/String;Ljava/util/List;Lkotlin/jvm/functions/Function0;Lme/proton/core/network/domain/client/ExtraHeaderProvider;Lme/proton/core/network/domain/client/ClientVersionValidator;Lme/proton/core/network/domain/serverconnection/DohAlternativesListener;[Ljava/lang/String;Lokhttp3/OkHttpClient;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun create (Lme/proton/core/network/domain/session/SessionId;Lkotlin/reflect/KClass;Ljava/util/List;[Ljava/lang/String;Ljava/util/List;)Lme/proton/core/network/domain/ApiManager;
public static synthetic fun create$default (Lme/proton/core/network/data/ApiManagerFactory;Lme/proton/core/network/domain/session/SessionId;Lkotlin/reflect/KClass;Ljava/util/List;[Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lme/proton/core/network/domain/ApiManager;
public final fun getBaseOkHttpClient ()Lokhttp3/OkHttpClient;
@@ -138,6 +138,9 @@ public final class me/proton/core/network/data/di/Constants {
public final fun getDOH_PROVIDERS_URLS ()[Ljava/lang/String;
}
public abstract interface annotation class me/proton/core/network/data/di/SharedOkHttpClient : java/lang/annotation/Annotation {
}
public final class me/proton/core/network/data/doh/DnsOverHttpsProviderRFC8484 : me/proton/core/network/domain/DohService {
public static final field Companion Lme/proton/core/network/data/doh/DnsOverHttpsProviderRFC8484$Companion;
public fun <init> (Lkotlin/jvm/functions/Function0;Ljava/lang/String;Lme/proton/core/network/domain/ApiClient;Lme/proton/core/network/domain/NetworkManager;)V
+1
View File
@@ -50,6 +50,7 @@ dependencies {
`android-annotation`,
`apacheCommon-codec`,
datastore,
`javax-inject`,
`miniDns`,
`okHttp-logging`,
`retrofit`,
@@ -67,6 +67,7 @@ import kotlin.reflect.KClass
* @param cookieStore The storage for cookies.
* @param cache [Cache] shared across all user, session, api or call.
*/
@Suppress("LongParameterList")
class ApiManagerFactory(
baseUrl: String,
private val apiClient: ApiClient,
@@ -87,7 +88,8 @@ class ApiManagerFactory(
private val extraHeaderProvider: ExtraHeaderProvider? = null,
private val clientVersionValidator: ClientVersionValidator,
private val dohAlternativesListener: DohAlternativesListener?,
private val dohProviderUrls: Array<String> = Constants.DOH_PROVIDERS_URLS
private val dohProviderUrls: Array<String> = Constants.DOH_PROVIDERS_URLS,
private val okHttpClient: OkHttpClient
) {
private val baseUri = URI(baseUrl)
@@ -110,7 +112,7 @@ class ApiManagerFactory(
require(clientVersionValidator.validate(apiClient.appVersionHeader)) {
"Invalid app version code: ${apiClient.appVersionHeader}."
}
OkHttpClient.Builder()
okHttpClient.newBuilder()
.cache(cache())
.connectTimeout(apiClient.timeoutSeconds, TimeUnit.SECONDS)
.writeTimeout(apiClient.timeoutSeconds, TimeUnit.SECONDS)
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2022 Proton Technologies AG
* This file is part of Proton AG and ProtonCore.
*
* ProtonCore is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonCore is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
*/
package me.proton.core.network.data.di
import javax.inject.Qualifier
/** Qualifier for a shared (singleton) instance of [okhttp3.OkHttpClient].
* Whenever you need a custom [okhttp3.OkHttpClient], inject this instance,
* and use [okhttp3.OkHttpClient.newBuilder] to adjust to your own needs.
*/
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class SharedOkHttpClient
@@ -161,7 +161,8 @@ internal class ApiManagerTests {
scope,
cache = { null },
clientVersionValidator = clientVersionValidator,
dohAlternativesListener = null
dohAlternativesListener = null,
okHttpClient = mockk(relaxed = true)
)
coEvery { dohService.getAlternativeBaseUrls(any(), any()) } returns listOf(proxy1url)
@@ -175,7 +175,8 @@ internal class HumanVerificationTests {
scope,
cache = { null },
clientVersionValidator = clientVersionValidator,
dohAlternativesListener = null
dohAlternativesListener = null,
okHttpClient = OkHttpClient()
)
every { networkManager.isConnectedToNetwork() } returns isNetworkAvailable
@@ -144,7 +144,8 @@ internal class ProtonApiBackendTests {
scope,
cache = { null },
clientVersionValidator = clientVersionValidator,
dohAlternativesListener = null
dohAlternativesListener = null,
okHttpClient = OkHttpClient()
)
every { networkManager.isConnectedToNetwork() } returns isNetworkAvailable