diff --git a/WordPress/src/main/java/org/wordpress/android/networking/restapi/WpComApiClientProvider.kt b/WordPress/src/main/java/org/wordpress/android/networking/restapi/WpComApiClientProvider.kt index 1bdb512e9126..5b86acc6f440 100644 --- a/WordPress/src/main/java/org/wordpress/android/networking/restapi/WpComApiClientProvider.kt +++ b/WordPress/src/main/java/org/wordpress/android/networking/restapi/WpComApiClientProvider.kt @@ -1,7 +1,10 @@ package org.wordpress.android.networking.restapi import okhttp3.OkHttpClient +import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider +import org.wordpress.android.util.AppLog +import rs.wordpress.api.kotlin.RequestErrorLogger import rs.wordpress.api.kotlin.WpComApiClient import rs.wordpress.api.kotlin.WpHttpClient import rs.wordpress.api.kotlin.WpRequestExecutor @@ -15,12 +18,14 @@ private const val CONNECT_TIMEOUT = 30L class WpComApiClientProvider @Inject constructor( private val networkAvailabilityProvider: WpNetworkAvailabilityProvider, + private val trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, ) { fun getWpComApiClient(accessToken: String): WpComApiClient { val okHttpClient = OkHttpClient.Builder() .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_WRITE_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(READ_WRITE_TIMEOUT, TimeUnit.SECONDS) + .addInterceptor(trackNetworkRequestsInterceptor) .build() return WpComApiClient( @@ -29,7 +34,8 @@ class WpComApiClientProvider @Inject constructor( networkAvailabilityProvider = networkAvailabilityProvider ), authProvider = WpAuthenticationProvider.staticWithAuth(WpAuthentication.Bearer(token = accessToken) - ) + ), + errorLogger = RequestErrorLogger { AppLog.e(AppLog.T.API, it) } ) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/accounts/applicationpassword/ApplicationPasswordsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/accounts/applicationpassword/ApplicationPasswordsViewModel.kt index faafa774c871..071e6c392c4d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/accounts/applicationpassword/ApplicationPasswordsViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/accounts/applicationpassword/ApplicationPasswordsViewModel.kt @@ -8,13 +8,12 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext import org.wordpress.android.R import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.utils.AppLogWrapper import org.wordpress.android.modules.IO_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.dataview.DataViewDropdownItem import org.wordpress.android.ui.dataview.DataViewFieldType import org.wordpress.android.ui.dataview.DataViewItem @@ -44,8 +43,7 @@ class ApplicationPasswordsViewModel @Inject constructor( sharedPrefs: SharedPreferences, networkUtilsWrapper: NetworkUtilsWrapper, @Named(IO_THREAD) ioDispatcher: CoroutineDispatcher, - trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - networkAvailabilityProvider: WpNetworkAvailabilityProvider, + wpComApiClientProvider: WpComApiClientProvider, ) : DataViewViewModel( mainDispatcher = mainDispatcher, appLogWrapper = appLogWrapper, @@ -54,8 +52,7 @@ class ApplicationPasswordsViewModel @Inject constructor( selectedSiteRepository = selectedSiteRepository, accountStore = accountStore, ioDispatcher = ioDispatcher, - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) { init { initialize() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/dataview/DataViewViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/dataview/DataViewViewModel.kt index 7f43d25c9b61..720e67be26db 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/dataview/DataViewViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/dataview/DataViewViewModel.kt @@ -21,13 +21,10 @@ import org.wordpress.android.modules.UI_THREAD import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.util.AppLog import org.wordpress.android.util.NetworkUtilsWrapper -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.viewmodel.ScopedViewModel import rs.wordpress.api.kotlin.WpComApiClient import uniffi.wp_api.WpApiParamOrder -import uniffi.wp_api.WpAuthentication -import uniffi.wp_api.WpAuthenticationProvider import javax.inject.Inject import javax.inject.Named @@ -45,8 +42,7 @@ open class DataViewViewModel @Inject constructor( private val selectedSiteRepository: SelectedSiteRepository, private val accountStore: AccountStore, @Named(IO_THREAD) protected val ioDispatcher: CoroutineDispatcher, - private val trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - private val networkAvailabilityProvider: WpNetworkAvailabilityProvider, + private val wpComApiClientProvider: WpComApiClientProvider, ) : ScopedViewModel(mainDispatcher) { private val _uiState = MutableStateFlow(DataViewUiState()) val uiState: StateFlow = _uiState.asStateFlow() @@ -82,16 +78,9 @@ open class DataViewViewModel @Inject constructor( } } - // TODO this is strictly for wp.com sites, we'll need different auth for self-hosted protected val wpComApiClient: WpComApiClient by lazy { - WpComApiClient( - authProvider = WpAuthenticationProvider.staticWithAuth( - requireNotNull(accountStore.accessToken) { "Access token is required but was null" }.let { token -> - WpAuthentication.Bearer(token = token) - } - ), - interceptors = listOf(trackNetworkRequestsInterceptor), - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider.getWpComApiClient( + requireNotNull(accountStore.accessToken) { "Access token is required but was null" } ) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/subscribers/AddSubscribersViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/subscribers/AddSubscribersViewModel.kt index 8d7a862c684a..3436fa8324fb 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/subscribers/AddSubscribersViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/subscribers/AddSubscribersViewModel.kt @@ -6,13 +6,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.withContext import org.wordpress.android.R -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.utils.AppLogWrapper import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.IO_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.util.AppLog import org.wordpress.android.util.ToastUtilsWrapper @@ -20,8 +19,6 @@ import org.wordpress.android.viewmodel.ScopedViewModel import rs.wordpress.api.kotlin.WpComApiClient import rs.wordpress.api.kotlin.WpRequestResult import uniffi.wp_api.AddSubscribersParams -import uniffi.wp_api.WpAuthentication -import uniffi.wp_api.WpAuthenticationProvider import javax.inject.Inject import javax.inject.Named @@ -31,8 +28,7 @@ class AddSubscribersViewModel @Inject constructor( @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, private val appLogWrapper: AppLogWrapper, private val toastUtilsWrapper: ToastUtilsWrapper, - private val trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - private val networkAvailabilityProvider: WpNetworkAvailabilityProvider, + private val wpComApiClientProvider: WpComApiClientProvider, ) : ScopedViewModel(bgDispatcher) { @Inject @Named(IO_THREAD) @@ -48,13 +44,7 @@ class AddSubscribersViewModel @Inject constructor( val showProgress = _showProgress.asStateFlow() private val wpComApiClient: WpComApiClient by lazy { - WpComApiClient( - WpAuthenticationProvider.staticWithAuth( - WpAuthentication.Bearer(token = accountStore.accessToken!!) - ), - interceptors = listOf(trackNetworkRequestsInterceptor), - networkAvailabilityProvider = networkAvailabilityProvider - ) + wpComApiClientProvider.getWpComApiClient(accountStore.accessToken!!) } private fun siteId(): Long { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/subscribers/SubscribersViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/subscribers/SubscribersViewModel.kt index 5471a36a88db..153ff39d44f9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/subscribers/SubscribersViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/subscribers/SubscribersViewModel.kt @@ -8,13 +8,12 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.withContext import org.wordpress.android.R -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.utils.AppLogWrapper import org.wordpress.android.models.wrappers.SimpleDateFormatWrapper import org.wordpress.android.modules.IO_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.dataview.DataViewDropdownItem import org.wordpress.android.ui.dataview.DataViewFieldType import org.wordpress.android.ui.dataview.DataViewItem @@ -45,8 +44,7 @@ class SubscribersViewModel @Inject constructor( selectedSiteRepository: SelectedSiteRepository, accountStore: AccountStore, @Named(IO_THREAD) ioDispatcher: CoroutineDispatcher, - trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - networkAvailabilityProvider: WpNetworkAvailabilityProvider, + wpComApiClientProvider: WpComApiClientProvider, ) : DataViewViewModel( mainDispatcher = mainDispatcher, appLogWrapper = appLogWrapper, @@ -55,8 +53,7 @@ class SubscribersViewModel @Inject constructor( selectedSiteRepository = selectedSiteRepository, accountStore = accountStore, ioDispatcher = ioDispatcher, - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) { private val _subscriberStats = MutableStateFlow(null) val subscriberStats = _subscriberStats.asStateFlow() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/taxonomies/TermsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/taxonomies/TermsViewModel.kt index c3f2b5f57226..9a1cf4687fbd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/taxonomies/TermsViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/taxonomies/TermsViewModel.kt @@ -19,9 +19,7 @@ import org.wordpress.android.fluxc.generated.TaxonomyActionBuilder import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.model.TermModel import org.wordpress.android.fluxc.model.TermsModel -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.TaxonomyStore import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_CATEGORY @@ -30,6 +28,7 @@ import org.wordpress.android.fluxc.store.TaxonomyStore.FetchTermsResponsePayload import org.wordpress.android.fluxc.utils.AppLogWrapper import org.wordpress.android.modules.IO_THREAD import org.wordpress.android.modules.UI_THREAD +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.dataview.DataViewDropdownItem import org.wordpress.android.ui.dataview.DataViewFieldType import org.wordpress.android.ui.dataview.DataViewItem @@ -89,8 +88,7 @@ class TermsViewModel @Inject constructor( sharedPrefs: SharedPreferences, networkUtilsWrapper: NetworkUtilsWrapper, @Named(IO_THREAD) ioDispatcher: CoroutineDispatcher, - trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - networkAvailabilityProvider: WpNetworkAvailabilityProvider, + wpComApiClientProvider: WpComApiClientProvider, ) : DataViewViewModel( mainDispatcher = mainDispatcher, appLogWrapper = appLogWrapper, @@ -99,8 +97,7 @@ class TermsViewModel @Inject constructor( selectedSiteRepository = selectedSiteRepository, accountStore = accountStore, ioDispatcher = ioDispatcher, - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) { private var taxonomySlug: String = "" private var isHierarchical: Boolean = false diff --git a/WordPress/src/test/java/org/wordpress/android/ui/dataview/DataViewViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/dataview/DataViewViewModelTest.kt index f21fd75134cb..f691296cfe5b 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/dataview/DataViewViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/dataview/DataViewViewModelTest.kt @@ -13,10 +13,9 @@ import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.R import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.utils.AppLogWrapper +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.dataview.DataViewViewModel.Companion.PAGE_SIZE import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.util.NetworkUtilsWrapper @@ -43,10 +42,7 @@ class DataViewViewModelTest : BaseUnitTest() { private lateinit var accountStore: AccountStore @Mock - private lateinit var trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor - - @Mock - private lateinit var networkAvailabilityProvider: WpNetworkAvailabilityProvider + private lateinit var wpComApiClientProvider: WpComApiClientProvider private val testSite = SiteModel().apply { id = 1 @@ -77,8 +73,7 @@ class DataViewViewModelTest : BaseUnitTest() { selectedSiteRepository = selectedSiteRepository, accountStore = accountStore, ioDispatcher = testDispatcher(), - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) } @@ -237,8 +232,7 @@ class DataViewViewModelTest : BaseUnitTest() { selectedSiteRepository = selectedSiteRepository, accountStore = accountStore, ioDispatcher = testDispatcher(), - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) // Access the wpComApiClient property to trigger the lazy initialization viewModel.testAccessWpComApiClient() @@ -506,8 +500,7 @@ class DataViewViewModelTest : BaseUnitTest() { selectedSiteRepository: SelectedSiteRepository, accountStore: AccountStore, ioDispatcher: kotlinx.coroutines.CoroutineDispatcher, - trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor, - networkAvailabilityProvider: WpNetworkAvailabilityProvider + wpComApiClientProvider: WpComApiClientProvider ) : DataViewViewModel( mainDispatcher, appLogWrapper, @@ -516,8 +509,7 @@ class DataViewViewModelTest : BaseUnitTest() { selectedSiteRepository, accountStore, ioDispatcher, - trackNetworkRequestsInterceptor, - networkAvailabilityProvider + wpComApiClientProvider ) { init { initialize() diff --git a/WordPress/src/test/java/org/wordpress/android/ui/taxonomies/TermsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/taxonomies/TermsViewModelTest.kt index c3ada275f82f..ecc570c5a4c0 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/taxonomies/TermsViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/taxonomies/TermsViewModelTest.kt @@ -17,14 +17,13 @@ import org.wordpress.android.BaseUnitTest import org.wordpress.android.R import org.wordpress.android.fluxc.Dispatcher import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.fluxc.network.TrackNetworkRequestsInterceptor import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider -import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpNetworkAvailabilityProvider import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.TaxonomyStore import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_CATEGORY import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_TAG import org.wordpress.android.fluxc.utils.AppLogWrapper +import org.wordpress.android.networking.restapi.WpComApiClientProvider import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.util.NetworkUtilsWrapper @@ -58,10 +57,7 @@ class TermsViewModelTest : BaseUnitTest() { private lateinit var fluxCDispatcher: Dispatcher @Mock - private lateinit var trackNetworkRequestsInterceptor: TrackNetworkRequestsInterceptor - - @Mock - private lateinit var networkAvailabilityProvider: WpNetworkAvailabilityProvider + private lateinit var wpComApiClientProvider: WpComApiClientProvider @Before fun setUp() { @@ -81,8 +77,7 @@ class TermsViewModelTest : BaseUnitTest() { ioDispatcher = testDispatcher(), taxonomyStore = taxonomyStore, fluxCDispatcher = fluxCDispatcher, - trackNetworkRequestsInterceptor = trackNetworkRequestsInterceptor, - networkAvailabilityProvider = networkAvailabilityProvider + wpComApiClientProvider = wpComApiClientProvider ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 41f28a8cb777..1c9400f5b859 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -101,7 +101,7 @@ wellsql = '2.0.0' wordpress-aztec = 'v2.1.4' wordpress-lint = '2.2.0' wordpress-persistent-edittext = '1.0.2' -wordpress-rs = '0.4.0' +wordpress-rs = '1398-ba6481de5f07565a6c69442f2d3a77b2c12f6d89' wordpress-utils = '3.14.0' automattic-ucrop = '2.2.11' zendesk = '5.5.3' diff --git a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt index 1de0014590d8..468d482c4f98 100644 --- a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt +++ b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/rs/WpApiClientProvider.kt @@ -9,6 +9,8 @@ import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.module.OkHttpClientQualifiers import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.WpAppNotifierHandler import org.wordpress.android.fluxc.store.AccountStore +import org.wordpress.android.util.AppLog +import rs.wordpress.api.kotlin.RequestErrorLogger import rs.wordpress.api.kotlin.WpApiClient import rs.wordpress.api.kotlin.WpHttpClient import rs.wordpress.api.kotlin.WpRequestExecutor @@ -36,6 +38,8 @@ class WpApiClientProvider @Inject constructor( private val wpComClients = mutableMapOf() private val selfHostedClients = mutableMapOf() + private val errorLogger = RequestErrorLogger { AppLog.e(AppLog.T.API, it) } + /** Removes all cached API clients (e.g. on sign-out). */ @Synchronized fun clearAllClients() { @@ -116,6 +120,7 @@ class WpApiClientProvider @Inject constructor( ) } }, + errorLogger = errorLogger, ) } @@ -155,7 +160,8 @@ class WpApiClientProvider @Inject constructor( override suspend fun requestedWithInvalidAuthentication(requestUrl: String) { wpAppNotifierHandler.notifyRequestedWithInvalidAuthentication(site) } - } + }, + errorLogger = errorLogger ) return client } @@ -175,7 +181,8 @@ class WpApiClientProvider @Inject constructor( override suspend fun requestedWithInvalidAuthentication(requestUrl: String) { wpAppNotifierHandler.notifyRequestedWithInvalidAuthentication(site) } - } + }, + errorLogger = errorLogger ) } }