diff --git a/.mapping.json b/.mapping.json index bbd6b11e1..e84e80c54 100644 --- a/.mapping.json +++ b/.mapping.json @@ -2009,8 +2009,11 @@ "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/ComposeFontFamilyProvider.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/ComposeFontFamilyProvider.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/RobotoFlexTypefaceProvider.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/RobotoFlexTypefaceProvider.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/YandexSansCondensedTypefaceProvider.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/font/YandexSansCondensedTypefaceProvider.kt", + "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionComposeViewCreator.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionComposeViewCreator.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDivActionHandler.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDivActionHandler.kt", + "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionSwitchingViewCreator.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionSwitchingViewCreator.kt", + "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/ScenarioJson.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/ScenarioJson.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/ComposeImageLoadingTracker.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/ComposeImageLoadingTracker.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/DivAssetReader.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/DivAssetReader.kt", "client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/DivComposeScreenshotActivity.kt":"divkit/public/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/screenshot/DivComposeScreenshotActivity.kt", @@ -17599,6 +17602,7 @@ "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt", "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioListAdapter.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioListAdapter.kt", "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioLogDelegate.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioLogDelegate.kt", + "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioViewCreator.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioViewCreator.kt", "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/SliderActivity.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/SliderActivity.kt", "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/data/AssetScenariosDataSource.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/data/AssetScenariosDataSource.kt", "client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/data/DataSourceBindings.kt":"divkit/public/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/data/DataSourceBindings.kt", diff --git a/client/android/divkit-demo-app/src/main/assets/application/settings.json b/client/android/divkit-demo-app/src/main/assets/application/settings.json index 8030bef07..9f8fb8b50 100644 --- a/client/android/divkit-demo-app/src/main/assets/application/settings.json +++ b/client/android/divkit-demo-app/src/main/assets/application/settings.json @@ -731,7 +731,7 @@ "items": [ { "type": "settings_item_title", - "text": "Compose Renderer by default" + "text": "Compose Renderer (Demo and testing)" }, { "type": "setting_switch_state", diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/Container.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/Container.kt index 1e535af58..31513c391 100644 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/Container.kt +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/Container.kt @@ -18,7 +18,9 @@ import com.yandex.divkit.demo.div.editor.NaiveSSLContext import com.yandex.divkit.demo.div.histogram.DemoHistogramConfiguration import com.yandex.divkit.demo.div.histogram.LoggingHistogramBridge import com.yandex.divkit.demo.div.video.DemoVideoCustomImageCache +import com.yandex.divkit.demo.regression.RegressionComposeViewCreator import com.yandex.divkit.demo.regression.RegressionDiv2ViewCreator +import com.yandex.divkit.demo.regression.RegressionSwitchingViewCreator import com.yandex.divkit.demo.settings.FlagPreferenceProvider import com.yandex.divkit.demo.settings.Preferences import com.yandex.divkit.demo.utils.DivkitDemoUriHandler @@ -111,9 +113,12 @@ internal object Container { val flagPreferenceProvider by lazy { FlagPreferenceProvider(context) } val regressionComponent by lazy { + val div2ViewCreator = RegressionDiv2ViewCreator(context) + val composeViewCreator = RegressionComposeViewCreator(context) `Yatagan$RegressionComponent`.builder().create( context = context, - viewCreator = RegressionDiv2ViewCreator(context) + div2ViewCreator = div2ViewCreator, + scenarioViewCreator = RegressionSwitchingViewCreator(div2ViewCreator, composeViewCreator), ) } 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 c49a9055c..8fa60ecc1 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 @@ -25,6 +25,9 @@ class DivkitApplication : Application(), HasRegressionTesting { override val regressionComponent: RegressionComponent get() = Container.regressionComponent + override val isComposeRendererEnabled: Boolean + get() = Container.preferences.useComposeRenderer + override fun onCreate() { super.onCreate() diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionComposeViewCreator.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionComposeViewCreator.kt new file mode 100644 index 000000000..d88df593d --- /dev/null +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionComposeViewCreator.kt @@ -0,0 +1,46 @@ +package com.yandex.divkit.demo.regression + +import android.app.Activity +import android.content.Context +import android.view.View +import androidx.compose.ui.platform.ComposeView +import com.yandex.div.compose.DivComposeConfiguration +import com.yandex.div.compose.DivContext +import com.yandex.div.compose.DivView as ComposeDivView +import com.yandex.div.data.DivParsingEnvironment +import com.yandex.div.json.ParsingErrorLogger +import com.yandex.div2.DivData +import com.yandex.divkit.demo.font.ComposeFontFamilyProvider +import com.yandex.divkit.demo.screenshot.DivAssetReader +import org.json.JSONObject + +class RegressionComposeViewCreator(context: Context) { + + private val assetReader = DivAssetReader(context) + + fun createView( + activity: Activity, + scenarioPath: String, + onBound: (View) -> Unit, + ) { + val (templatesJson, cardJson) = assetReader.readScenarioJson(scenarioPath) + val divData = parseDivData(templatesJson, cardJson) + val composeDivContext = DivContext( + baseContext = activity, + configuration = DivComposeConfiguration( + fontFamilyProvider = ComposeFontFamilyProvider(activity), + ) + ) + val composeView = ComposeView(composeDivContext).apply { + setContent { ComposeDivView(data = divData) } + } + onBound(composeView) + } + + private fun parseDivData(templatesJson: JSONObject?, cardJson: JSONObject): DivData { + val environment = DivParsingEnvironment(ParsingErrorLogger.LOG).apply { + if (templatesJson != null) parseTemplates(templatesJson) + } + return DivData(environment, cardJson) + } +} diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt index 9a63f59e6..813c12207 100644 --- a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionDiv2ViewCreator.kt @@ -22,7 +22,6 @@ import com.yandex.divkit.demo.utils.DivkitDemoUriHandler import com.yandex.divkit.demo.utils.lifecycleOwner import com.yandex.divkit.regression.Div2ViewCreator import com.yandex.divkit.regression.ScenarioLogDelegate -import org.json.JSONObject import java.util.concurrent.Executors class RegressionDiv2ViewCreator(context: Context) : Div2ViewCreator { @@ -42,17 +41,9 @@ class RegressionDiv2ViewCreator(context: Context) : Div2ViewCreator { logDelegate: ScenarioLogDelegate, onBound: (Div2View) -> Unit ) { - val divContext = createContext(activity, parent, logDelegate) - - val divJson = assetReader.read(scenarioPath) - when { - divJson.has("card") -> { - val templateJson = parseTemplates(divJson) - val cardJson = parseCard(divJson) - Div2ViewFactory(divContext, templateJson).createAndBindViewByConfig(cardJson, onBound) - } - else -> Div2ViewFactory(divContext).createAndBindViewByConfig(divJson, onBound) - } + val divContext = createDiv2Context(activity, parent, logDelegate) + val (templatesJson, cardJson) = assetReader.readScenarioJson(scenarioPath) + Div2ViewFactory(divContext, templatesJson).createAndBindViewByConfig(cardJson, onBound) } override fun createDiv2ViewSync( @@ -61,20 +52,12 @@ class RegressionDiv2ViewCreator(context: Context) : Div2ViewCreator { parent: ViewGroup, logDelegate: ScenarioLogDelegate, ): Div2View { - val divContext = createContext(activity, parent, logDelegate) - - val divJson = assetReader.read(scenarioPath) - return when { - divJson.has("card") -> { - val templateJson = parseTemplates(divJson) - val cardJson = parseCard(divJson) - Div2ViewFactory(divContext, templateJson).createAndBindViewSync(cardJson) - } - else -> Div2ViewFactory(divContext).createAndBindViewSync(divJson) - } + val divContext = createDiv2Context(activity, parent, logDelegate) + val (templatesJson, cardJson) = assetReader.readScenarioJson(scenarioPath) + return Div2ViewFactory(divContext, templatesJson).createAndBindViewSync(cardJson) } - private fun createContext( + private fun createDiv2Context( activity: Activity, parent: ViewGroup, logDelegate: ScenarioLogDelegate @@ -105,15 +88,4 @@ class RegressionDiv2ViewCreator(context: Context) : Div2ViewCreator { } } - private fun parseTemplates( - divJson: JSONObject, - ): JSONObject? { - return divJson.optJSONObject("templates") - } - - private fun parseCard( - divJson: JSONObject, - ): JSONObject { - return divJson.getJSONObject("card") - } } diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionSwitchingViewCreator.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionSwitchingViewCreator.kt new file mode 100644 index 000000000..863bb20b6 --- /dev/null +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/RegressionSwitchingViewCreator.kt @@ -0,0 +1,28 @@ +package com.yandex.divkit.demo.regression + +import android.app.Activity +import android.view.View +import android.view.ViewGroup +import com.yandex.divkit.demo.Container +import com.yandex.divkit.regression.ScenarioLogDelegate +import com.yandex.divkit.regression.ScenarioViewCreator + +class RegressionSwitchingViewCreator( + private val div2ViewCreator: RegressionDiv2ViewCreator, + private val composeViewCreator: RegressionComposeViewCreator, +) : ScenarioViewCreator { + + override fun createView( + activity: Activity, + scenarioPath: String, + parent: ViewGroup, + logDelegate: ScenarioLogDelegate, + onBound: (View) -> Unit, + ) { + if (Container.preferences.useComposeRenderer) { + composeViewCreator.createView(activity, scenarioPath, onBound) + } else { + div2ViewCreator.createDiv2ViewByConfig(activity, scenarioPath, parent, logDelegate, onBound) + } + } +} diff --git a/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/ScenarioJson.kt b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/ScenarioJson.kt new file mode 100644 index 000000000..b834d1120 --- /dev/null +++ b/client/android/divkit-demo-app/src/main/java/com/yandex/divkit/demo/regression/ScenarioJson.kt @@ -0,0 +1,17 @@ +package com.yandex.divkit.demo.regression + +import com.yandex.divkit.demo.screenshot.DivAssetReader +import org.json.JSONObject + +internal data class ScenarioJson( + val templatesJson: JSONObject?, + val cardJson: JSONObject, +) + +internal fun DivAssetReader.readScenarioJson(scenarioPath: String): ScenarioJson { + val divJson = read(scenarioPath) + return ScenarioJson( + templatesJson = divJson.optJSONObject("templates"), + cardJson = divJson.getJSONObject("card"), + ) +} diff --git a/client/android/divkit-demo-app/src/main/res/values/strings.xml b/client/android/divkit-demo-app/src/main/res/values/strings.xml index e91cf7fc5..4916aff05 100644 --- a/client/android/divkit-demo-app/src/main/res/values/strings.xml +++ b/client/android/divkit-demo-app/src/main/res/values/strings.xml @@ -33,5 +33,5 @@ Load patch Load another div json Close all tooltips - Compose Renderer (Demo) + Compose Renderer (Demo and testing) diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/RegressionActivity.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/RegressionActivity.kt index 55f17373e..1f4da5e70 100644 --- a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/RegressionActivity.kt +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/RegressionActivity.kt @@ -16,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView.Adapter.StateRestorationPolicy import com.yandex.div.internal.Assert import com.yandex.divkit.regression.databinding.RegressionActivityBinding import com.yandex.divkit.regression.di.provideDiv2ViewCreator +import com.yandex.divkit.regression.di.provideIsComposeRendererEnabled import kotlinx.coroutines.flow.FlowCollector private const val TAG_FILTER_MENU_ID = 1 @@ -38,7 +39,7 @@ class RegressionActivity : AppCompatActivity() { binding = RegressionActivityBinding.inflate(layoutInflater) setSupportActionBar(binding.regressionToolbar) - binding.toolbarLayout.title = getString(R.string.regression_label) + updateToolbarTitle() val config: Configuration = resources.configuration val icon = if (config.layoutDirection == View.LAYOUT_DIRECTION_RTL) { R.drawable.ic_back_rtl @@ -79,6 +80,16 @@ class RegressionActivity : AppCompatActivity() { } } + override fun onResume() { + super.onResume() + updateToolbarTitle() + } + + private fun updateToolbarTitle() { + val suffix = if (provideIsComposeRendererEnabled()) " (Compose)" else "" + binding.toolbarLayout.title = getString(R.string.regression_label) + suffix + } + override fun onPrepareOptionsMenu(menu: Menu?): Boolean { if (menu == null) return super.onPrepareOptionsMenu(menu) val tagFilterSubMenu = menu.findItem(TAG_FILTER_MENU_ID).subMenu diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt index 116935ab2..76624ccd1 100644 --- a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioActivity.kt @@ -17,7 +17,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.yandex.divkit.regression.data.Scenario import com.yandex.divkit.regression.databinding.ScenarioActivityBinding -import com.yandex.divkit.regression.di.provideDiv2ViewCreator +import com.yandex.divkit.regression.di.provideScenarioViewCreator import com.yandex.divkit.regression.di.provideScenariosRepository import com.yandex.divkit.regression.utils.shortMessage @@ -31,7 +31,7 @@ private const val INVALID_POSITION = -1 class ScenarioActivity : AppCompatActivity(), MetadataBottomSheet.ScenarioHost { private lateinit var binding: ScenarioActivityBinding private val repository by lazy(LazyThreadSafetyMode.NONE) { provideScenariosRepository() } - private val div2ViewCreator by lazy(LazyThreadSafetyMode.NONE) { provideDiv2ViewCreator() } + private val scenarioViewCreator by lazy(LazyThreadSafetyMode.NONE) { provideScenarioViewCreator() } private val logging = mutableListOf() private val logDelegate = ScenarioLogDelegate { message -> logging += message } @@ -135,7 +135,7 @@ class ScenarioActivity : AppCompatActivity(), MetadataBottomSheet.ScenarioHost { } } binding.singleContainer.isVisible = true - div2ViewCreator.createDiv2ViewByConfig( + scenarioViewCreator.createView( this, "regression_test_data/${scenario.file}", binding.singleContainer, diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioViewCreator.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioViewCreator.kt new file mode 100644 index 000000000..9c74abe4b --- /dev/null +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/ScenarioViewCreator.kt @@ -0,0 +1,15 @@ +package com.yandex.divkit.regression + +import android.app.Activity +import android.view.View +import android.view.ViewGroup + +fun interface ScenarioViewCreator { + fun createView( + activity: Activity, + scenarioPath: String, + parent: ViewGroup, + logDelegate: ScenarioLogDelegate, + onBound: (View) -> Unit, + ) +} diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/HasRegressionTesting.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/HasRegressionTesting.kt index 202ad0b4d..6e0fab74e 100644 --- a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/HasRegressionTesting.kt +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/HasRegressionTesting.kt @@ -2,4 +2,5 @@ package com.yandex.divkit.regression.di interface HasRegressionTesting { val regressionComponent: RegressionComponent + val isComposeRendererEnabled: Boolean get() = false } diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/Providers.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/Providers.kt index d51d4c4a0..6eb396a13 100644 --- a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/Providers.kt +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/Providers.kt @@ -2,9 +2,15 @@ package com.yandex.divkit.regression.di import android.content.Context -internal fun Context.provideRegressionComponent() = - (applicationContext as HasRegressionTesting).regressionComponent +internal fun Context.provideHasRegressionTesting() = + applicationContext as HasRegressionTesting + +internal fun Context.provideRegressionComponent() = provideHasRegressionTesting().regressionComponent internal fun Context.provideScenariosRepository() = provideRegressionComponent().scenariosRepository internal fun Context.provideDiv2ViewCreator() = provideRegressionComponent().div2ViewCreator + +internal fun Context.provideScenarioViewCreator() = provideRegressionComponent().scenarioViewCreator + +internal fun Context.provideIsComposeRendererEnabled() = provideHasRegressionTesting().isComposeRendererEnabled diff --git a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/RegressionComponent.kt b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/RegressionComponent.kt index 92fa51557..e67a4a77e 100644 --- a/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/RegressionComponent.kt +++ b/client/android/divkit-regression-testing/src/main/java/com/yandex/divkit/regression/di/RegressionComponent.kt @@ -2,6 +2,7 @@ package com.yandex.divkit.regression.di import android.content.Context import com.yandex.divkit.regression.Div2ViewCreator +import com.yandex.divkit.regression.ScenarioViewCreator import com.yandex.divkit.regression.data.DataSourceBindings import com.yandex.divkit.regression.data.ScenariosRepository import com.yandex.yatagan.BindsInstance @@ -14,12 +15,14 @@ interface RegressionComponent { val scenariosRepository: ScenariosRepository val div2ViewCreator: Div2ViewCreator + val scenarioViewCreator: ScenarioViewCreator @Component.Builder interface Factory { fun create( @BindsInstance context: Context, - @BindsInstance viewCreator: Div2ViewCreator + @BindsInstance div2ViewCreator: Div2ViewCreator, + @BindsInstance scenarioViewCreator: ScenarioViewCreator, ): RegressionComponent } }