diff --git a/.mapping.json b/.mapping.json index 98a524386..281526e2e 100644 --- a/.mapping.json +++ b/.mapping.json @@ -667,6 +667,7 @@ "client/android/div-data/src/main/java/com/yandex/div/internal/util/JsonUtils.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/internal/util/JsonUtils.kt", "client/android/div-data/src/main/java/com/yandex/div/json/JSONSerializable.java":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/JSONSerializable.java", "client/android/div-data/src/main/java/com/yandex/div/json/JsonTemplate.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/JsonTemplate.kt", + "client/android/div-data/src/main/java/com/yandex/div/json/LoadingErrorLogger.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/LoadingErrorLogger.kt", "client/android/div-data/src/main/java/com/yandex/div/json/ParsingEnvironment.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/ParsingEnvironment.kt", "client/android/div-data/src/main/java/com/yandex/div/json/ParsingEnvironmentExtensions.kt":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/ParsingEnvironmentExtensions.kt", "client/android/div-data/src/main/java/com/yandex/div/json/ParsingErrorLogger.java":"divkit/public/client/android/div-data/src/main/java/com/yandex/div/json/ParsingErrorLogger.java", @@ -847,6 +848,12 @@ "client/android/div-markdown/jacoco.excludes":"divkit/public/client/android/div-markdown/jacoco.excludes", "client/android/div-markdown/proguard-rules.pro":"divkit/public/client/android/div-markdown/proguard-rules.pro", "client/android/div-markdown/src/main/java/com/yandex/div/markdown/DivMarkdownExtensionHandler.kt":"divkit/public/client/android/div-markdown/src/main/java/com/yandex/div/markdown/DivMarkdownExtensionHandler.kt", + "client/android/div-network/build.gradle":"divkit/public/client/android/div-network/build.gradle", + "client/android/div-network/jacoco.excludes":"divkit/public/client/android/div-network/jacoco.excludes", + "client/android/div-network/proguard-rules.pro":"divkit/public/client/android/div-network/proguard-rules.pro", + "client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivDownloader.kt":"divkit/public/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivDownloader.kt", + "client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivRequestExecutor.kt":"divkit/public/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivRequestExecutor.kt", + "client/android/div-network/src/main/java/com/yandex/div/network/DivParsingExtensions.kt":"divkit/public/client/android/div-network/src/main/java/com/yandex/div/network/DivParsingExtensions.kt", "client/android/div-pinch-to-zoom/build.gradle":"divkit/public/client/android/div-pinch-to-zoom/build.gradle", "client/android/div-pinch-to-zoom/jacoco.excludes":"divkit/public/client/android/div-pinch-to-zoom/jacoco.excludes", "client/android/div-pinch-to-zoom/proguard-rules.pro":"divkit/public/client/android/div-pinch-to-zoom/proguard-rules.pro", @@ -1823,9 +1830,7 @@ "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoCustomContainerAdapter.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoCustomContainerAdapter.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDiv2Logger.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDiv2Logger.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivCustomViewAdapter.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivCustomViewAdapter.kt", - "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivDownloader.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivDownloader.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivLottieRawResProvider.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivLottieRawResProvider.kt", - "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivRequestExecutor.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivRequestExecutor.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoGlobalVariablesController.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoGlobalVariablesController.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoNestedScrollView.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoNestedScrollView.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/Div2Activity.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/Div2Activity.kt", diff --git a/client/android/div-data/src/main/java/com/yandex/div/json/LoadingErrorLogger.kt b/client/android/div-data/src/main/java/com/yandex/div/json/LoadingErrorLogger.kt new file mode 100644 index 000000000..98145f3e4 --- /dev/null +++ b/client/android/div-data/src/main/java/com/yandex/div/json/LoadingErrorLogger.kt @@ -0,0 +1,21 @@ +package com.yandex.div.json + +import com.yandex.div.internal.Assert +import com.yandex.div.internal.KLog + +interface LoadingErrorLogger { + fun logError(e: Exception) + + companion object { + val ASSERT: LoadingErrorLogger = object : LoadingErrorLogger { + override fun logError(e: Exception) { + Assert.fail(e.message, e) + } + } + val LOG: LoadingErrorLogger = object : LoadingErrorLogger { + override fun logError(e: Exception) { + KLog.e("LoadingErrorLogger", e) { "An error occurred during loading process" } + } + } + } +} diff --git a/client/android/div-network/build.gradle b/client/android/div-network/build.gradle new file mode 100644 index 000000000..13c67a840 --- /dev/null +++ b/client/android/div-network/build.gradle @@ -0,0 +1,12 @@ +apply from: "${project.projectDir}/../div-library.gradle" +apply from: "${project.projectDir}/../div-tests.gradle" +apply from: "${project.projectDir}/../publish-android.gradle" + +android { + namespace 'com.yandex.div.network' +} + +dependencies { + implementation project(path: ':div') + implementation libs.okhttp +} diff --git a/client/android/div-network/jacoco.excludes b/client/android/div-network/jacoco.excludes new file mode 100644 index 000000000..231d1f0fb --- /dev/null +++ b/client/android/div-network/jacoco.excludes @@ -0,0 +1,7 @@ +##################### +# Generated classes # +##################### +**/R.class +**/R$*.class +**/BuildConfig.* +**/Manifest*.* diff --git a/client/android/div-network/proguard-rules.pro b/client/android/div-network/proguard-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivDownloader.kt b/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivDownloader.kt new file mode 100644 index 000000000..8fbb4bc22 --- /dev/null +++ b/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivDownloader.kt @@ -0,0 +1,118 @@ +package com.yandex.div.network + +import com.yandex.div.core.downloader.DivDownloader +import com.yandex.div.core.downloader.DivPatchDownloadCallback +import com.yandex.div.core.images.LoadReference +import com.yandex.div.core.view2.Div2View +import com.yandex.div.histogram.DivParsingHistogramReporter +import com.yandex.div.json.LoadingErrorLogger +import com.yandex.div.json.ParsingErrorLogger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch +import kotlinx.coroutines.cancel +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException + +/** + * The [downloadJson] function defines how raw JSON is fetched from a URL, + * allowing integration with different HTTP clients. + */ +class DefaultDivDownloader( + private val downloadJson: suspend (url: String) -> Result, + private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default), + private val histogramReporter: DivParsingHistogramReporter = DivParsingHistogramReporter.DEFAULT, + private val parsingErrorLogger: ParsingErrorLogger = ParsingErrorLogger.LOG, + private val loadingErrorLogger: LoadingErrorLogger = LoadingErrorLogger.LOG, +) : DivDownloader { + + @JvmOverloads + constructor( + client: OkHttpClient, + scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default), + histogramReporter: DivParsingHistogramReporter = DivParsingHistogramReporter.DEFAULT, + parsingErrorLogger: ParsingErrorLogger = ParsingErrorLogger.LOG, + loadingErrorLogger: LoadingErrorLogger = LoadingErrorLogger.LOG + ) : this( + downloadJson = { url -> client.downloadJson(url) }, + scope = scope, + histogramReporter = histogramReporter, + parsingErrorLogger = parsingErrorLogger, + loadingErrorLogger = loadingErrorLogger, + ) + + override fun downloadPatch( + divView: Div2View, + downloadUrl: String, + callback: DivPatchDownloadCallback + ): LoadReference { + val job = scope.launch { + val json: String = try { + val result = downloadJson(downloadUrl) + result.getOrElse { t -> + logFailAndNotify(downloadUrl, t, callback) + return@launch + } + } catch (e: Exception) { + logFailAndNotify(downloadUrl, e, callback) + return@launch + } + + val patch = try { + JSONObject(json).asDivPatchWithTemplates(histogramReporter, parsingErrorLogger) + } catch (e: JSONException) { + parsingErrorLogger.logError( + IllegalArgumentException("Failed to parse patch JSON from $downloadUrl", e) + ) + notifyMain { callback.onFail() } + return@launch + } + + notifyMain { callback.onSuccess(patch) } + } + + return LoadReference { job.cancel("cancel all downloads") } + } + + private suspend fun notifyMain(action: suspend () -> Unit) { + withContext(Dispatchers.Main) { action() } + } + + private suspend fun logFailAndNotify( + downloadUrl: String, + cause: Throwable, + callback: DivPatchDownloadCallback + ) { + loadingErrorLogger.logError( + IOException("Failed to download patch from $downloadUrl", cause) + ) + notifyMain { callback.onFail() } + } +} + +private suspend fun OkHttpClient.downloadJson(uri: String): Result { + return withContext(Dispatchers.IO) { + val request = Request.Builder() + .url(uri) + .get() + .build() + + newCall(request).execute().use { resp -> + if (!resp.isSuccessful) { + return@use Result.failure( + IOException("HTTP ${resp.code} ${resp.message} for $uri") + ) + } + val body = resp.body?.string() + ?: return@use Result.failure( + IllegalStateException("Empty response body for $uri") + ) + Result.success(body) + } + } +} diff --git a/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivRequestExecutor.kt b/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivRequestExecutor.kt new file mode 100644 index 000000000..3ecb70eb5 --- /dev/null +++ b/client/android/div-network/src/main/java/com/yandex/div/network/DefaultDivRequestExecutor.kt @@ -0,0 +1,91 @@ +package com.yandex.div.network + +import com.yandex.div.core.DivRequestExecutor +import com.yandex.div.core.images.LoadReference +import com.yandex.div.json.LoadingErrorLogger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import java.io.IOException + +/** + * The [executeRequest] function — network request handler, pluggable for different HTTP clients. + */ +class DefaultDivRequestExecutor( + private val executeRequest: suspend (DivRequestExecutor.Request) -> Result, + private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO), + private val loadingErrorLogger: LoadingErrorLogger = LoadingErrorLogger.LOG, +) : DivRequestExecutor { + + @JvmOverloads + constructor( + client: OkHttpClient, + scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO), + loadingErrorLogger: LoadingErrorLogger = LoadingErrorLogger.LOG, + ) : this( + executeRequest = { request -> client.executeRequest(request) }, + scope = scope, + loadingErrorLogger = loadingErrorLogger, + ) + + override fun execute( + request: DivRequestExecutor.Request, + callback: DivRequestExecutor.Callback? + ): LoadReference { + val job = scope.launch(Dispatchers.Main) { + try { + val result = withContext(Dispatchers.IO) { + executeRequest(request) + } + result + .onSuccess { callback?.onSuccess() } + .onFailure { err -> + logFailAndNotify(request, err, callback) + } + } catch (e: Exception) { + logFailAndNotify(request, e, callback) + } + } + + return LoadReference { job.cancel("Cancel submit action") } + } + + private fun logFailAndNotify( + request: DivRequestExecutor.Request, + cause: Throwable, + callback: DivRequestExecutor.Callback? + ) { + loadingErrorLogger.logError( + IllegalStateException( + "Error while executing request [${request.method} ${request.url}]", cause + ) + ) + callback?.onFail() + } +} + +private suspend fun OkHttpClient.executeRequest( + request: DivRequestExecutor.Request +): Result { + val httpRequest = Request.Builder() + .url(request.url.toString()) + .method(request.method, request.body.toRequestBody()) + .apply { request.headers?.forEach { addHeader(it.name, it.value) } } + .build() + + newCall(httpRequest).execute().use { resp -> + return if (resp.isSuccessful) { + Result.success(Unit) + } else { + Result.failure( + IOException("HTTP request failed ${resp.code} ${resp.message} [${request.method} ${request.url}]") + ) + } + } +} diff --git a/client/android/div-network/src/main/java/com/yandex/div/network/DivParsingExtensions.kt b/client/android/div-network/src/main/java/com/yandex/div/network/DivParsingExtensions.kt new file mode 100644 index 000000000..0d1185611 --- /dev/null +++ b/client/android/div-network/src/main/java/com/yandex/div/network/DivParsingExtensions.kt @@ -0,0 +1,31 @@ +package com.yandex.div.network + +import com.yandex.div.data.DivParsingEnvironment +import com.yandex.div.histogram.DivParsingHistogramReporter +import com.yandex.div.json.ParsingErrorLogger +import com.yandex.div2.DivPatch +import org.json.JSONObject + +internal fun JSONObject.asDivPatchWithTemplates( + histogramReporter: DivParsingHistogramReporter, + errorLogger: ParsingErrorLogger, +): DivPatch { + val templates = optJSONObject("templates") + val card = getJSONObject("patch") + + val environment = DivParsingEnvironment(errorLogger) + templates?.let { + environment.parseTemplatesWithHistograms(it, histogramReporter) + } + + return DivPatch(environment, card) +} + +private fun DivParsingEnvironment.parseTemplatesWithHistograms( + templates: JSONObject, + histogramReporter: DivParsingHistogramReporter, +) { + histogramReporter.measureTemplatesParsing(templates, null) { + parseTemplates(templates) + } +} diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java b/client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java index 5d0e02535..72fff0643 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java +++ b/client/android/div/src/main/java/com/yandex/div/core/DivConfiguration.java @@ -582,6 +582,9 @@ public class DivConfiguration { return this; } + /** + * A default implementation, [DefaultDivDownloader], is available. + */ @NonNull public Builder divDownloader(@NonNull DivDownloader divDownloader) { mDivDownloader = divDownloader; diff --git a/client/android/div/src/main/java/com/yandex/div/core/DivRequestExecutor.kt b/client/android/div/src/main/java/com/yandex/div/core/DivRequestExecutor.kt index be95f0815..5a38aa792 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/DivRequestExecutor.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/DivRequestExecutor.kt @@ -3,6 +3,9 @@ package com.yandex.div.core import android.net.Uri import com.yandex.div.core.images.LoadReference +/** + * A default implementation, [DefaultDivRequestExecutor], is available. + */ interface DivRequestExecutor { class Header(val name: String, val value: String) diff --git a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivDownloader.java b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivDownloader.java index 02fd5ee47..51adc37d2 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/downloader/DivDownloader.java +++ b/client/android/div/src/main/java/com/yandex/div/core/downloader/DivDownloader.java @@ -7,6 +7,7 @@ import com.yandex.div.core.view2.Div2View; /** * Downloads patches for Divs + * A default implementation, [DefaultDivDownloader], is provided. */ @PublicApi public interface DivDownloader { diff --git a/client/android/divkit-demo-app/build.gradle b/client/android/divkit-demo-app/build.gradle index a53bea6d6..4980e0edc 100644 --- a/client/android/divkit-demo-app/build.gradle +++ b/client/android/divkit-demo-app/build.gradle @@ -88,6 +88,7 @@ dependencies { implementation project(path: ':div-json') implementation project(path: ':div-lottie') implementation project(path: ':div-markdown') + implementation project(path: ':div-network') implementation project(path: ':div-pinch-to-zoom') implementation project(path: ':div-rive') implementation project(path: ':div-shimmer') diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/DivkitApplication.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/DivkitApplication.kt index e9ba65428..c49a9055c 100644 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/DivkitApplication.kt +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/DivkitApplication.kt @@ -8,9 +8,9 @@ import com.yandex.android.beacon.SendBeaconPerWorkerLogger import com.yandex.div.core.DivKit import com.yandex.div.core.DivKitConfiguration import com.yandex.div.internal.Assert +import com.yandex.div.network.DefaultDivRequestExecutor import com.yandex.divkit.demo.beacon.SendBeaconRequestExecutorImpl import com.yandex.divkit.demo.beacon.SendBeaconWorkerSchedulerImpl -import com.yandex.divkit.demo.div.DemoDivRequestExecutor import com.yandex.divkit.demo.utils.VisualAssertionErrorHandler import com.yandex.divkit.regression.di.HasRegressionTesting import com.yandex.divkit.regression.di.RegressionComponent @@ -67,7 +67,7 @@ class DivkitApplication : Application(), HasRegressionTesting { DivKitConfiguration.Builder() .sendBeaconConfiguration(configureSendBeacon(okHttpClient)) .histogramConfiguration(Container::histogramConfiguration) - .divRequestExecutor { DemoDivRequestExecutor(okHttpClient) } + .divRequestExecutor { DefaultDivRequestExecutor(Container.httpClient)} .build() ) diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivDownloader.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivDownloader.kt deleted file mode 100644 index 13b211b89..000000000 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivDownloader.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.yandex.divkit.demo.div - -import com.yandex.div.core.downloader.DivDownloader -import com.yandex.div.core.downloader.DivPatchDownloadCallback -import com.yandex.div.core.images.LoadReference -import com.yandex.div.core.view2.Div2View -import com.yandex.divkit.demo.Container -import com.yandex.divkit.demo.utils.loadText -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch -import org.json.JSONException -import org.json.JSONObject - -class DemoDivDownloader : DivDownloader { - - override fun downloadPatch(divView: Div2View, downloadUrl: String, callback: DivPatchDownloadCallback): LoadReference { - val job = GlobalScope.launch(Dispatchers.Main) { - val json = Container.httpClient.loadText(downloadUrl) - if (json != null) { - try { - callback.onSuccess(JSONObject(json).asDivPatchWithTemplates()) - } catch (e: JSONException) { - callback.onFail() - } - } else { - callback.onFail() - } - } - return LoadReference { - job.cancel("cancel all downloads") - } - } -} diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivRequestExecutor.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivRequestExecutor.kt deleted file mode 100644 index fe62c7d77..000000000 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DemoDivRequestExecutor.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.yandex.divkit.demo.div - -import com.yandex.div.core.DivRequestExecutor -import com.yandex.div.core.images.LoadReference -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.RequestBody.Companion.toRequestBody - -class DemoDivRequestExecutor(private val okHttpClient: OkHttpClient) : DivRequestExecutor { - - private val scope = MainScope() - - override fun execute(request: DivRequestExecutor.Request, callback: DivRequestExecutor.Callback?): LoadReference { - val job = scope.launch(Dispatchers.Main) { - runCatching { - withContext(Dispatchers.IO) { - okHttpClient.newCall(request.toHttpRequest()).execute() - } - }.getOrNull() ?: run { - callback?.onFail() - return@launch - } - callback?.onSuccess() - } - return LoadReference { job.cancel("Cancel submit action") } - } - - private fun DivRequestExecutor.Request.toHttpRequest(): Request { - return Request.Builder() - .url(url.toString()) - .method(method, body.toRequestBody()) - .apply { - headers?.forEach { addHeader(it.name, it.value) } - } - .build() - } -} diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DivUtils.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DivUtils.kt index a0ef36dbe..622a9c1c1 100644 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DivUtils.kt +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/div/DivUtils.kt @@ -26,6 +26,7 @@ import com.yandex.div.json.templates.CachingTemplateProvider import com.yandex.div.json.templates.InMemoryTemplateProvider import com.yandex.div.json.templates.TemplateProvider import com.yandex.div.markdown.DivMarkdownExtensionHandler +import com.yandex.div.network.DefaultDivDownloader import com.yandex.div.shimmer.DivShimmerExtensionHandler import com.yandex.div.shine.DivShineExtensionHandler import com.yandex.div.shine.DivShineLogger @@ -79,7 +80,7 @@ fun divConfiguration( flagPreferenceProvider.getExperimentFlag(Experiment.RENDER_EFFECT_ENABLED) ) .tooltipRestrictor { _, _, _, _ -> true } - .divDownloader(DemoDivDownloader()) + .divDownloader(DefaultDivDownloader(Container.httpClient)) .typefaceProvider(YandexSansDivTypefaceProvider(activity)) .additionalTypefaceProviders( mapOf( diff --git a/client/android/settings.gradle b/client/android/settings.gradle index cb8d15b2b..b10571603 100644 --- a/client/android/settings.gradle +++ b/client/android/settings.gradle @@ -35,6 +35,7 @@ include ':div-histogram' include ':div-json' include ':div-lottie' include ':div-markdown' +include ':div-network' include ':div-pinch-to-zoom' include ':div-rive' include ':div-shimmer'