Skip to content

Commit

Permalink
Fix oppia#2942: Add support for LaTeX math tags via SVG rendering [Bl…
Browse files Browse the repository at this point in the history
…ocked: oppia#2980] (oppia#2981)

* Add support for loading proto versions of lessons.

* Upgrade Espresso versions to work around build issues.

Note that I can't actually verify Espresso tests are working with these
versions since the Bazel project doesn't yet have Espresso tests set up.

* Lint fix post-copying from oppia#2927.

* Fix Glide in Bazel.

* Fix concept card name escaping.

Also, refactor HtmlParser to better support/handling different tag types
& prepare for LaTeX SVG image support.

* Copy over test fix from oppia#2927.

* Add support for rendering LaTeX via SVGs.

Much of this is copied from oppia#2927 so see that PR's commit history & the
PR corresponding to this commit for specific details.

* Remove image loading annotation.

This will be added in a later branch in the chain.

* Add caching module to needed test suites.

* Re-add image load annotation for this PR.

* Add support for importing text protos as assets.

This actually provides Bazel-only support for converting text protos to
binary and including those as assets so that we can avoid checking in
binary protos to the codebase.

* Add gitignore for Android Studio Bazel plugin output.

* Import textproto versions of existing dev assets.

This imports local conversions of all existing dev assets as text proto
leveraging the Bazel-only conversion system to convert these to binary
protos and include them as assets.

This is a necessary step to both eventually replace JSON assets with
text proto, and to test that the new proto loading pipeline is working
as designed.

* Undo Espresso version change since it breaks Bazel tests.

* Fix tests.

Various attempts to fix existing tests + move some of the domain tests
over to actually using proto when running with Bazel.

App module tests are hanging currently for unknown reasons (only in
Bazel).

* Use correct Espresso core.

3.1.0 causes tests to hang indefinitely when run with Bazel.

* Move coroutine dispatchers.

This moves the coroutine dispatchers to a new threading subpackage. It
also simplifies the TestCoroutineDispatcher interface & implementations
(which required moving runUntilIdle to CoroutineExecutorServiceTest).

The test coroutine annotations were also moved to their own files.

* Refactor testing utilities build graph.

This introduces new Bazel libraries for:
- Test dispatchers
- Fake system/Oppia clocks
- Robolectric dependencies

* Introduce dedicated test for TestCoroutineDispatcher.

This also fixes some threading issues in the dispatcher, and clarifies
some of its API that was previously unclear (and can lead to subtle race
conditions).

* Add tests for TestCoroutineDispatcher.

This required a bunch of refactoring, adding the first examples of
dedicated Bazel test build files, and introducing a new test pattern for
sharing code between different implementations. Further, it refined the
API for TesCoroutineDispatcher & fixed some issues in the
implementations (especially Robolectric).

Tests verified as non-flaky in Robolectric across 1000 runs, and 0.2%
flaky across 1000 runs for Espresso (though that may be fixed; waiting
on a follow-up run to confirm stability).

* Workaround ktlint semicolon issue.

* Lint fixes.

* Fix test post-merge.

* Move CoroutineDispatcher to be part of threading.

* Lint fixes.

* Undo version upgrade.

* Fix broken tests.

* Lint fixes.

* Add a bit more proto loading test coverage.

* Comment fix.

* Lint fixes.

* Address earlier TODO.

* Post-merge restructure.

* Post-merge fixes.

This removes unneeded dependencies from PersistentCacheStore, including
Glide.

* Add tests for new tag handlers.

Also, add tests for HtmlParser, and clean up some existing tests.

* Fix broken test build.

* Post-merge lint fixes.

* Lint fixes.

* Address reviewer comment.

* Post-merge fix.

* Address pre-merge TODO.

* Disable local image loading.

Also, add specific LaTeX line in the first fractions interaction so that
the new SVG support can be tested.

* Fix typo.

* Docs + tests.

This adds more documentation & context for code added before without it.
It also adds a bunch of new testing coverage for changes. The tests are
particularly around the html part of the LaTeX loading pipeline, but not
the image parts.

More of both will be needed specifically for the image loading pipeline
changes.

* Docs + tests + refactor.

This adds documentation for all remaining components introduced in oppia#2981,
adds some testing for UrlImageParser, and cleans up the image loading
pipeline to be a bit simpler & cleaner (though this will probably break
down-stream PRs relying on image transformations).

* Lint fixes.

* Fix lint failure & re-enable assets.
  • Loading branch information
BenHenning authored Apr 23, 2021
1 parent b283acc commit 0cf6d11
Show file tree
Hide file tree
Showing 35 changed files with 1,363 additions and 238 deletions.
9 changes: 9 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ git_repository(
remote = "https://github.com/oppia/CircularImageview",
)

# A custom version of Android SVG is needed since custom changes needed to be added to the library
# to correctly size in-line SVGs (such as those needed for LaTeX-based math expressions).
git_repository(
name = "androidsvg",
commit = "6bd15f69caee3e6857fcfcd123023716b4adec1d",
remote = "https://github.com/oppia/androidsvg",
)

bind(
name = "databinding_annotation_processor",
actual = "//tools/android:compiler_annotation_processor",
Expand All @@ -136,6 +144,7 @@ load("@rules_jvm_external//:defs.bzl", "maven_install")
# Note to developers: new dependencies should be added to //third_party:versions.bzl, not here.
maven_install(
artifacts = DAGGER_ARTIFACTS + get_maven_dependencies(),
fetch_sources = True,
repositories = DAGGER_REPOSITORIES + [
"https://bintray.com/bintray/jcenter",
"https://jcenter.bintray.com/",
Expand Down
2 changes: 1 addition & 1 deletion app/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ kt_android_library(
"//third_party:androidx_viewpager2_viewpager2",
"//third_party:androidx_viewpager_viewpager",
"//third_party:androidx_work_work-runtime-ktx",
"//third_party:com_caverock_androidsvg-aar",
"//third_party:com_caverock_androidsvg",
"//third_party:com_google_android_flexbox",
"//third_party:javax_annotation_javax_annotation-api_jar",
"//utility",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class LessonThumbnailImageView @JvmOverloads constructor(
)
val imageUrl = "$gcsPrefix/$resourceBucketName/$imageName"
if (imageUrl.endsWith("svg", ignoreCase = true)) {
imageLoader.loadSvg(imageUrl, ImageViewTarget(this), transformations)
imageLoader.loadBlockSvg(imageUrl, ImageViewTarget(this), transformations)
} else {
imageLoader.loadBitmap(imageUrl, ImageViewTarget(this), transformations)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class ImageRegionSelectionInteractionView @JvmOverloads constructor(
val imageName = String.format(imageDownloadUrlTemplate, entityType, entityId, imageUrl)
val imageUrl = "$gcsPrefix/$resourceBucketName/$imageName"
if (imageUrl.endsWith("svg", ignoreCase = true)) {
imageLoader.loadSvg(imageUrl, ImageViewTarget(this))
imageLoader.loadBlockSvg(imageUrl, ImageViewTarget(this))
} else {
imageLoader.loadBitmap(imageUrl, ImageViewTarget(this))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
package org.oppia.android.app.testing

import android.os.Bundle
import android.text.Spannable
import android.widget.TextView
import org.oppia.android.R
import org.oppia.android.app.activity.InjectableAppCompatActivity
import org.oppia.android.util.gcsresource.DefaultResourceBucketName
import org.oppia.android.util.parser.HtmlParser
import javax.inject.Inject

/** This is a dummy activity to test Html parsing. */
class HtmlParserTestActivity : InjectableAppCompatActivity() {
@Inject
lateinit var htmlParserFactory: HtmlParser.Factory

@Inject
@field:DefaultResourceBucketName
lateinit var resourceBucketName: String

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityComponent.inject(this)
setContentView(R.layout.test_html_parser_activity)

val testHtmlContentTextView: TextView = findViewById(R.id.test_html_content_text_view)
val rawDummyString =
"\u003cp\u003e\"Let's try one last question,\" said Mr. Baker. \"Here's a pineapple cake cut into pieces.\"\u003c/p\u003e\u003coppia-noninteractive-image alt-with-value=\"\u0026amp;quot;Pineapple cake with 7/9 having cherries.\u0026amp;quot;\" caption-with-value=\"\u0026amp;quot;\u0026amp;quot;\" filepath-with-value=\"\u0026amp;quot;pineapple_cake_height_479_width_480.png\u0026amp;quot;\"\u003e\u003c/oppia-noninteractive-image\u003e\u003cp\u003e\u00a0\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eQuestion 6\u003c/strong\u003e: What fraction of the cake has big red cherries in the pineapple slices?\u003c/p\u003e" // ktlint-disable max-line-length
val htmlResult: Spannable =
htmlParserFactory.create(
resourceBucketName,
/* entityType= */ "exploration",
/* entityId= */ "oppia",
/* imageCenterAlign= */ false
).parseOppiaHtml(
rawDummyString,
testHtmlContentTextView
)
testHtmlContentTextView.text = htmlResult
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
import org.oppia.android.domain.oppialogger.loguploader.WorkManagerConfigurationModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
import org.oppia.android.testing.TestImageLoaderModule
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.mockito.capture
import org.oppia.android.testing.robolectric.RobolectricModule
Expand All @@ -79,10 +80,10 @@ import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
import org.oppia.android.util.parser.CustomBulletSpan
import org.oppia.android.util.parser.GlideImageLoaderModule
import org.oppia.android.util.parser.HtmlParser
import org.oppia.android.util.parser.HtmlParserEntityTypeModule
import org.oppia.android.util.parser.ImageParsingModule
import org.oppia.android.util.parser.TestGlideImageLoader
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
Expand All @@ -109,6 +110,9 @@ class HtmlParserTest {
@Inject
lateinit var htmlParserFactory: HtmlParser.Factory

@Inject
lateinit var testGlideImageLoader: TestGlideImageLoader

@Inject
@field:DefaultResourceBucketName
lateinit var resourceBucketName: String
Expand Down Expand Up @@ -152,6 +156,7 @@ class HtmlParserTest {
"fraction of the cake has big red cherries in the pineapple slices?\u003c/p\u003e",
textView
)
textView.text = htmlResult
return@runWithActivity textView to htmlResult
}
assertThat(textView.text.toString()).isEqualTo(htmlResult.toString())
Expand Down Expand Up @@ -287,6 +292,56 @@ class HtmlParserTest {
assertThat(htmlResult.toString()).doesNotContain(" ")
}

@Test
fun testHtmlContent_withPngImage_loadsBitmap() {
val htmlParser = htmlParserFactory.create(
resourceBucketName,
entityType = "",
entityId = "",
imageCenterAlign = true,
)
activityRule.scenario.runWithActivity {
val textView: TextView = it.findViewById(R.id.test_html_content_text_view)
val htmlResult: Spannable = htmlParser.parseOppiaHtml(
"A<oppia-noninteractive-image filepath-with-value=\"test.png\">" +
"</oppia-noninteractive-image>",
textView,
supportsLinks = true,
supportsConceptCards = true
)
textView.text = htmlResult
}

val loadedBitmaps = testGlideImageLoader.getLoadedBitmaps()
assertThat(loadedBitmaps).hasSize(1)
assertThat(loadedBitmaps.first()).contains("test.png")
}

@Test
fun testHtmlContent_withSvgImage_loadsBlockSvg() {
val htmlParser = htmlParserFactory.create(
resourceBucketName,
entityType = "",
entityId = "",
imageCenterAlign = true,
)
activityRule.scenario.runWithActivity {
val textView: TextView = it.findViewById(R.id.test_html_content_text_view)
val htmlResult: Spannable = htmlParser.parseOppiaHtml(
"A<oppia-noninteractive-image filepath-with-value=\"test.svg\">" +
"</oppia-noninteractive-image>",
textView,
supportsLinks = true,
supportsConceptCards = true
)
textView.text = htmlResult
}

val loadedBlockImages = testGlideImageLoader.getLoadedBlockSvgs()
assertThat(loadedBlockImages).hasSize(1)
assertThat(loadedBlockImages.first()).contains("test.svg")
}

@Test
fun testHtmlContent_withConceptCard_conceptCardSupportDisabled_ignoresConceptCard() {
val htmlParser = htmlParserFactory.create(
Expand Down Expand Up @@ -422,6 +477,33 @@ class HtmlParserTest {
onView(withId(R.id.test_html_content_text_view)).perform(click())
}

@Test
fun testHtmlContent_withMathTag_loadsTextSvg() {
val htmlParser = htmlParserFactory.create(
resourceBucketName,
entityType = "",
entityId = "",
imageCenterAlign = true,
)
activityRule.scenario.runWithActivity {
val textView: TextView = it.findViewById(R.id.test_html_content_text_view)
val htmlResult: Spannable = htmlParser.parseOppiaHtml(
"<oppia-noninteractive-math math_content-with-value=\"{" +
"&amp;quot;raw_latex&amp;quot;:&amp;quot;\\\\frac{2}{5}&amp;quot;,&amp;quot;" +
"svg_filename&amp;quot;:&amp;quot;math_image1.svg&amp;quot;}\">" +
"</oppia-noninteractive-math>",
textView,
supportsLinks = true,
supportsConceptCards = true
)
textView.text = htmlResult
}

val loadedInlineImages = testGlideImageLoader.getLoadedTextSvgs()
assertThat(loadedInlineImages).hasSize(1)
assertThat(loadedInlineImages.first()).contains("math_image1.svg")
}

private fun <A : Activity> ActivityScenario<A>.getDimensionPixelSize(
@DimenRes dimenResId: Int
): Int {
Expand Down Expand Up @@ -463,7 +545,7 @@ class HtmlParserTest {
ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
NumberWithUnitsRuleModule::class, NumericInputRuleModule::class, TextInputRuleModule::class,
DragDropSortInputModule::class, ImageClickInputModule::class, InteractionsModule::class,
GcsResourceModule::class, GlideImageLoaderModule::class, ImageParsingModule::class,
GcsResourceModule::class, TestImageLoaderModule::class, ImageParsingModule::class,
HtmlParserEntityTypeModule::class, QuestionModule::class, TestLogReportingModule::class,
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}

Expand Down
2 changes: 1 addition & 1 deletion domain/src/main/assets/umPkwp0L1M0-.json
Original file line number Diff line number Diff line change
Expand Up @@ -2308,7 +2308,7 @@
"classifier_model_id": null,
"content": {
"content_id": "content",
"html": "<p>“That’s correct!\" said Mr. Baker. \"You see, a fraction tells us two things: <strong>how many</strong> parts we want, and the <strong>type</strong> of each of the parts.</p><p>\"It’s quicker to use numbers rather than words to write fractions. So, instead of writing 'two fifths', we can write 2/5':</p><ul><li>The first number tells us <strong>how many </strong>parts we want. For example, if the first number is 2, that means we want 2 parts.</li><li>The second number tells us the <strong>total number</strong> of equal parts, so that we know how large each part is. For example, if the second number is 5, that means the whole picture is divided into 5 equal parts.</li></ul><p>\"Here's another example. Look carefully at the following picture:</p><oppia-noninteractive-image alt-with-value=\"&amp;quot;Circle divided into sixths, with four pieces shaded, and 4/6 written next to it.&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180204_000837_8c5rjy0thh_height_114_width_490.png&amp;quot;\"></oppia-noninteractive-image><p>\"This picture is divided into <strong>six equal parts</strong>, so our fraction looks like ?/6. <strong>Four</strong> of the parts are yellow, so the fraction of the circle that is yellow is 4/6.<br></p><p>\"Now, take a look at this cake.\"<br></p><p></p><oppia-noninteractive-image alt-with-value=\"&amp;quot;cake with 2/7 shaded&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180107_012145_7vyp98k71i_height_192_width_192.png&amp;quot;\"></oppia-noninteractive-image><p>\"Which of these fractions describes the darker part of the cake?\"<br></p>"
"html": "<p>“That’s correct!\" said Mr. Baker. \"You see, a fraction tells us two things: <strong>how many</strong> parts we want, and the <strong>type</strong> of each of the parts.</p><p>\"It’s quicker to use numbers rather than words to write fractions. So, instead of writing 'two fifths', we can write '&nbsp;<oppia-noninteractive-math math_content-with-value=\"{&amp;quot;raw_latex&amp;quot;:&amp;quot;\\\\frac{2}{5}&amp;quot;,&amp;quot;svg_filename&amp;quot;:&amp;quot;mathImg_20200902_074843_tfuk03203x_height_3d329_width_1d666_vertical_1d072.svg&amp;quot;}\"></oppia-noninteractive-math>&nbsp;' or '2/5'. Here's how to understand these numbers:\"</p>\n\n<ul><li>The first number tells us <strong>how many </strong>parts we want. For example, if the first number is 2, that means we want 2 parts.</li><li>The second number tells us the <strong>total number</strong> of equal parts, so that we know how large each part is. For example, if the second number is 5, that means the whole picture is divided into 5 equal parts.</li></ul><p>\"Here's another example. Look carefully at the following picture:</p><oppia-noninteractive-image alt-with-value=\"&amp;quot;Circle divided into sixths, with four pieces shaded, and 4/6 written next to it.&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180204_000837_8c5rjy0thh_height_114_width_490.png&amp;quot;\"></oppia-noninteractive-image><p>\"This picture is divided into <strong>six equal parts</strong>, so our fraction looks like ?/6. <strong>Four</strong> of the parts are yellow, so the fraction of the circle that is yellow is 4/6.<br></p><p>\"Now, take a look at this cake.\"<br></p><p></p><oppia-noninteractive-image alt-with-value=\"&amp;quot;cake with 2/7 shaded&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180107_012145_7vyp98k71i_height_192_width_192.png&amp;quot;\"></oppia-noninteractive-image><p>\"Which of these fractions describes the darker part of the cake?\"<br></p>"
},
"written_translations": {
"translations_mapping": {
Expand Down
2 changes: 1 addition & 1 deletion domain/src/main/assets/umPkwp0L1M0-.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -2689,7 +2689,7 @@ states {
}
}
content {
html: "<p>\342\200\234That\342\200\231s correct!\" said Mr. Baker. \"You see, a fraction tells us two things: <strong>how many</strong> parts we want, and the <strong>type</strong> of each of the parts.</p><p>\"It\342\200\231s quicker to use numbers rather than words to write fractions. So, instead of writing \'two fifths\', we can write\302\2402/5\':</p><ul><li>The first number tells us <strong>how many </strong>parts we want. For example, if the first number is 2, that means we want 2 parts.</li><li>The second number tells us the <strong>total number</strong> of equal parts, so that we know how large each part is. For example, if the second number is 5, that means the whole picture is divided into 5 equal parts.</li></ul><p>\"Here\'s another example. Look\302\240carefully at the following picture:</p><oppia-noninteractive-image alt-with-value=\"&amp;quot;Circle divided into sixths, with four pieces shaded, and 4/6 written next to it.&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180204_000837_8c5rjy0thh_height_114_width_490.png&amp;quot;\"></oppia-noninteractive-image><p>\"This picture is divided into\302\240<strong>six\302\240equal parts</strong>, so our fraction looks like\302\240?/6. <strong>Four</strong> of the parts are yellow, so the fraction of the circle that is yellow is\302\2404/6.<br></p><p>\"Now, take a look at this cake.\"<br></p><p></p><oppia-noninteractive-image alt-with-value=\"&amp;quot;cake with 2/7 shaded&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180107_012145_7vyp98k71i_height_192_width_192.png&amp;quot;\"></oppia-noninteractive-image><p>\"Which of these fractions describes the darker part of the cake?\"<br></p>"
html: "<p>\342\200\234That\342\200\231s correct!\" said Mr. Baker. \"You see, a fraction tells us two things: <strong>how many</strong> parts we want, and the <strong>type</strong> of each of the parts.</p><p>\"It\342\200\231s quicker to use numbers rather than words to write fractions. So, instead of writing \'two fifths\', we can write \'&nbsp;<oppia-noninteractive-math math_content-with-value=\"{&amp;quot;raw_latex&amp;quot;:&amp;quot;\\\\frac{2}{5}&amp;quot;,&amp;quot;svg_filename&amp;quot;:&amp;quot;mathImg_20200902_074843_tfuk03203x_height_3d329_width_1d666_vertical_1d072.svg&amp;quot;}\"></oppia-noninteractive-math>&nbsp;\' or \'2/5\'. Here\'s how to understand these numbers:\"</p>\n\n<ul><li>The first number tells us <strong>how many </strong>parts we want. For example, if the first number is 2, that means we want 2 parts.</li><li>The second number tells us the <strong>total number</strong> of equal parts, so that we know how large each part is. For example, if the second number is 5, that means the whole picture is divided into 5 equal parts.</li></ul><p>\"Here\'s another example. Look\302\240carefully at the following picture:</p><oppia-noninteractive-image alt-with-value=\"&amp;quot;Circle divided into sixths, with four pieces shaded, and 4/6 written next to it.&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180204_000837_8c5rjy0thh_height_114_width_490.png&amp;quot;\"></oppia-noninteractive-image><p>\"This picture is divided into\302\240<strong>six\302\240equal parts</strong>, so our fraction looks like\302\240?/6. <strong>Four</strong> of the parts are yellow, so the fraction of the circle that is yellow is\302\2404/6.<br></p><p>\"Now, take a look at this cake.\"<br></p><p></p><oppia-noninteractive-image alt-with-value=\"&amp;quot;cake with 2/7 shaded&amp;quot;\" caption-with-value=\"&amp;quot;&amp;quot;\" filepath-with-value=\"&amp;quot;img_20180107_012145_7vyp98k71i_height_192_width_192.png&amp;quot;\"></oppia-noninteractive-image><p>\"Which of these fractions describes the darker part of the cake?\"<br></p>"
content_id: "content"
}
written_translations {
Expand Down
10 changes: 10 additions & 0 deletions third_party/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ android_library(
],
)

# A wrapper dependency for the custom Git import of Android SVG (so that dependencies on this
# library still routes through //third_party).
android_library(
name = "com_caverock_androidsvg",
visibility = ["//visibility:public"],
exports = [
"@androidsvg//androidsvg",
],
)

android_library(
name = "robolectric_android-all",
visibility = ["//visibility:public"],
Expand Down
1 change: 0 additions & 1 deletion third_party/versions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ MAVEN_PRODUCTION_DEPENDENCY_VERSIONS = {
"androidx.work:work-runtime": "2.4.0",
"androidx.work:work-runtime-ktx": "2.4.0",
"com.android.support:support-annotations": "28.0.0",
"com.caverock:androidsvg-aar": "1.4",
"com.chaos.view:pinview": "1.4.4",
"com.crashlytics.sdk.android:crashlytics": "2.9.8",
"com.github.bumptech.glide:compiler": "4.11.0",
Expand Down
2 changes: 1 addition & 1 deletion utility/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ kt_android_library(
"//third_party:androidx_room_room-runtime",
"//third_party:androidx_work_work-runtime",
"//third_party:androidx_work_work-runtime-ktx",
"//third_party:com_caverock_androidsvg-aar",
"//third_party:com_caverock_androidsvg",
"//third_party:com_github_bumptech_glide_glide",
"//third_party:com_google_guava_guava",
"//third_party:glide_compiler",
Expand Down
2 changes: 1 addition & 1 deletion utility/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dependencies {
'androidx.appcompat:appcompat:1.0.2',
'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha03',
'androidx.work:work-runtime-ktx:2.4.0',
'com.caverock:androidsvg-aar:1.4',
'com.github.oppia:androidsvg:6bd15f69caee3e6857fcfcd123023716b4adec1d',
'com.github.bumptech.glide:glide:4.11.0',
'com.google.dagger:dagger:2.24',
'com.google.firebase:firebase-analytics-ktx:17.5.0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ class CachingModule {
@Provides
@LoadLessonProtosFromAssets
fun provideLoadLessonProtosFromAssets(): Boolean = false

@Provides
@LoadImagesFromAssets
fun provideLoadImagesFromAssets(): Boolean = false
}
Loading

0 comments on commit 0cf6d11

Please sign in to comment.