Skip to content

Fix part of #5663: Use local thumbnails in dev builds#6136

Draft
harshsomankar123-tech wants to merge 6 commits intooppia:developfrom
harshsomankar123-tech:fix-thumbnail-dev-builds
Draft

Fix part of #5663: Use local thumbnails in dev builds#6136
harshsomankar123-tech wants to merge 6 commits intooppia:developfrom
harshsomankar123-tech:fix-thumbnail-dev-builds

Conversation

@harshsomankar123-tech
Copy link
Copy Markdown
Contributor

Explanation

Fix #5663 Part 01: Fixes activity thumbnail loading in developer builds by introducing a debug-only ContentProvider.

Context:
Currently, when thumbnailFilename is set in the proto files, it constructs a GCS URL and tries to fetch the image from the internet. Because developer builds don't have access to these GCS assets, the thumbnail loading fails. (The JSON loading path previously avoided this by falling back to local LessonThumbnailGraphic drawables, but that path is being removed).

Changes in this PR:

  • Introduces a developer/debug-only ContentProvider that intercepts thumbnail requests. For developer builds, it serves the local drawable assets instead of attempting to fetch GCS images.
  • Adds a debug-only Dagger module to configure this specific behavior for developer builds, ensuring the current GCS pipeline remains completely unchanged in production.

(Note: This PR strictly handles the thumbnail fix for dev builds. The JSON loading path removal is handled separately).

Essential Checklist

  • The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
  • Any changes to scripts/assets files have their rationale included in the PR explanation.
  • The PR follows the style guide.
  • The PR does not contain any unnecessary code changes from Android Studio (reference).
  • The PR is made from a branch that's not called "develop" and is up-to-date with "develop".
  • The PR is assigned to the appropriate reviewers (reference).

@harshsomankar123-tech
Copy link
Copy Markdown
Contributor Author

harshsomankar123-tech commented Mar 9, 2026

@BenHenning @adhiamboperes PTAL

@BenHenning
Copy link
Copy Markdown
Member

Apologies--hoping to look at this tomorrow.

Copy link
Copy Markdown
Member

@BenHenning BenHenning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harshsomankar123-tech I left one comment on the PR and another on the issue. I don't think that this is being approached quite the correct way, PTAL.

Also, your PR description says that you've solved this with a custom ContentProvider but no ContentProvider has actually been proposed in code here.

listOf()
}
if (lessonThumbnail.thumbnailFilename.isNotEmpty()) {
if (lessonThumbnail.thumbnailFilename.isNotEmpty() && loadThumbnailsFromGcs) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested this with proto lessons @harshsomankar123-tech? I wouldn't expect this to work, actually. I left more thoughts in #5663 (comment). PTAL.

@harshsomankar123-tech
Copy link
Copy Markdown
Contributor Author

@BenHenning Thanks for the suggestions. I’ve made the changes mentioned in your comments.PTAL

@oppiabot
Copy link
Copy Markdown

oppiabot bot commented Mar 19, 2026

Unassigning @harshsomankar123-tech since a re-review was requested. @harshsomankar123-tech, please make sure you have addressed all review comments. Thanks!

Copy link
Copy Markdown
Member

@BenHenning BenHenning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @harshsomankar123-tech! This is definitely on the right track. I have a bunch of comments, PTAL.

Also, after you address all of my comments could you add a video to the PR description showing loading with protos having correct thumbnails? Please make sure to correctly set up loading via CachingModule since protos aren't loaded by default in local dev builds currently.

sortOrder: String?
): Cursor? = null

override fun getType(uri: Uri): String = "image/png"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? Perhaps these could be SVGs, instead?

Comment on lines +48 to +54
"baker.img" to R.drawable.lesson_thumbnail_graphic_baker,
"child_with_book.img" to R.drawable.lesson_thumbnail_graphic_child_with_book,
"child_with_cupcakes.img" to R.drawable.lesson_thumbnail_graphic_child_with_cupcakes,
"child_with_fractions_homework.img" to
R.drawable.lesson_thumbnail_graphic_child_with_fractions_homework,
"duck_and_chicken.img" to R.drawable.lesson_thumbnail_graphic_duck_and_chicken,
"person_with_pie_chart.img" to R.drawable.lesson_thumbnail_graphic_person_with_pie_chart
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be cleaner to represent these as SVGs? We converted them to drawables originally because of how they were hooked up, but SVGs could be embedded as assets and returned directly (avoiding any temporarily file creation or loading needed).

@@ -0,0 +1,111 @@
package org.oppia.android.app.application.dev
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think org.oppia.android.app.utility.imageloading is probably an okay place for now. This is a new pattern so we don't have an obvious place for it to go, but the current package is meant for top-level application setup which doesn't seem like the correct place.

The new package will need to be a proper Bazel package (i.e. with a BUILD.bazel) file, and you'll need to reference that new library target as a dependency for the top-level //:oppia_dev target as one of its dependencies.

is_published: true
has_practice_questions: true
topic_thumbnail {
thumbnail_filename: "child_with_fractions_homework.img"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here & elsewhere: how did you decide on which thumbnails to use? We ought to match exactly the current JSON behavior to make it an easier before-and-after check.

Comment on lines +372 to +375
<provider
android:name=".app.application.dev.ThumbnailContentProvider"
android:authorities="org.oppia.android.provider"
android:exported="false" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to go into its own AndroidManifest.xml in the same package as the content provider. We will rely on the manifest merge to include this at the end. Adding it here means we need to ship the provider in production which we absolutely don't want to do.

@DefaultGcsPrefix
@Singleton
fun provideDefaultGcsPrefix(): String {
return "content://org.oppia.android.provider"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use content://org.oppia.android.provider/gcs so as to not pollute future content provider potential.

kt_android_library(
name = "dev_image_parsing_module",
srcs = [
"DevImageParsingModule.kt",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention in the codebase is to use 'debug' for developer dependencies, and to put it at the end of the name before module, e.g. ImageParsingDebugModule. Please make sure to also update the library target name.

Comment on lines +35 to +38
addURI(AUTHORITY, "*/*/*/*/#", THUMBNAIL_MATCH)
addURI(AUTHORITY, "*/*/*/*", THUMBNAIL_MATCH)
addURI(AUTHORITY, "thumbnail/*", THUMBNAIL_MATCH)
addURI(AUTHORITY, "#", THUMBNAIL_MATCH)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all of these needed? It seems like we will subpath based on <entity_type>/<entity_id>/assets/<image|thumbnail>/<file.name> which seems like it only needs a single URI matcher, or am I missing something?

@oppiabot
Copy link
Copy Markdown

oppiabot bot commented Mar 28, 2026

Hi @harshsomankar123-tech, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue.
If you are still working on this PR, please make a follow-up commit within 3 days (and submit it for review, if applicable). Please also let us know if you are stuck so we can help you! If you're unsure how to reassign this PR to a reviewer, please make sure to review the wiki page that details the Guidance on submitting PRs.

@oppiabot oppiabot bot added the stale Corresponds to items that haven't seen a recent update and may be automatically closed. label Mar 28, 2026
@harshsomankar123-tech harshsomankar123-tech marked this pull request as draft March 28, 2026 00:44
@oppiabot oppiabot bot removed the stale Corresponds to items that haven't seen a recent update and may be automatically closed. label Mar 28, 2026
@adhiamboperes
Copy link
Copy Markdown
Contributor

adhiamboperes commented Apr 8, 2026

@harshsomankar123-tech, please feel free to share any issues you are facing with this PR here or in Github Discussions.

@harshsomankar123-tech
Copy link
Copy Markdown
Contributor Author

@adhiamboperes The CI is failing right now. I’ll work on fixing it and provide an update shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Remove JSON files & fix activity thumbnails

3 participants