Skip to content

fix(avatar): decode and save the remote avatar off the main thread - #6863

Merged
mahibi merged 4 commits into
nextcloud:masterfrom
ToteMeiSter:fix/provider-main-avatar
Oct 15, 2026
Merged

mahibi merged 4 commits into
nextcloud:masterfrom
ToteMeiSter:fix/provider-main-avatar

Conversation

@ToteMeiSter

Copy link
Copy Markdown
Contributor

PickImage.handleAvatar decoded the thumbnail stream and wrote the PNG
inside the Retrofit callback, which runs on the main thread. Do both in
the activity's lifecycleScope on Dispatchers.IO and launch the picker
back on the main thread.

🤖 Generated with Claude Code

PickImage.handleAvatar decoded the thumbnail stream and wrote the PNG
inside the Retrofit callback, which runs on the main thread. Do both in
the activity's lifecycleScope on Dispatchers.IO and launch the picker
back on the main thread.

Assisted-by: Claude-Code:claude-sonnet-5-5
Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru>
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 05f7ea4a-1006-4404-86d4-ba0e3c9abb3a
📥 Commits

Reviewing files that changed from the base of the PR and between a0d9a78 and ca2a708.

📒 Files selected for processing: 1
  • app/src/test/java/com/nextcloud/talk/utils/PickImageTest.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

📝 Walkthrough

PickImage now requires a ComponentActivity. Avatar responses are decoded and saved as PNG on Dispatchers.IO. Successful saves open the local image picker. Decode, save, and download failures are logged and show a long error toast. Robolectric tests cover missing and invalid response bodies, write failures, directory targets, valid PNG saves, and response-body closure when the scope is cancelled.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to ca2a7

Remote-avatar decoding and PNG writing now run off the main thread before the picker opens. Existing callers meet the updated activity requirement, and no actionable merge-blocking risk remains in the reviewed changes.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description explains the main code change and identifies AI assistance, but it omits the required Screenshots, TODO, and Checklist sections from the repository template. Add the required template sections: Screenshots, TODO, and Checklist. Complete the checklist items or mark them as not needed, including tests, capability, backport, milestone, and PR title checks.
Docstring Coverage Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes moving remote avatar decoding and saving off the main thread.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rapterjet2004 rapterjet2004 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, moving the decode and the PNG write off the main thread looks right, and returning instead of crashing on response.body()!! is an improvement.

One change before this goes in: failures are now completely silent. An error response (null body), a thumbnail that doesn't decode, a failed PNG write, and onFailure (still // unused atm) all end with nothing happening. From the user's side, they pick a file and nothing happens. Please show an error to the user in these cases, e.g. a toast with R.string.nc_common_error_sorry on the main thread, and log the cause.

Small optional nit: the response body is never closed. Reading it inside body.use { BitmapFactory.decodeStream(it.byteStream()) } would fix that (pre-existing).

A response without a body, a thumbnail that does not decode, a failed PNG
write and onFailure all ended silently, so picking a file did nothing from
the user's side. Log the cause and show R.string.nc_common_error_sorry on
the main thread. Close the response body after decoding.

Assisted-by: Claude-Code:claude-sonnet-5-5
Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8916c517-e56d-446f-ae75-e6ba65c9c75b
📥 Commits

Reviewing files that changed from the base of the PR and between 976034c and 8e4c6f9.

📒 Files selected for processing (2)
  • app/src/main/java/com/nextcloud/talk/utils/PickImage.kt
  • app/src/test/java/com/nextcloud/talk/utils/PickImageTest.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Comment thread app/src/main/java/com/nextcloud/talk/utils/PickImage.kt
…stroyed

If the activity is destroyed between onResponse and the coroutine start,
lifecycleScope.launch never runs the block, so the body returned by
Retrofit stayed open. Close it from the job's completion handler; closing
twice is safe.

Assisted-by: Claude-Code:claude-sonnet-5-5
Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru>
@ToteMeiSter

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Pushed 8e4c6f9 and a0d9a78:

  • All four failure paths (no body, thumbnail that doesn't decode, failed PNG write incl. Bitmap.compress returning false, and onFailure) now log the cause and show a R.string.nc_common_error_sorry toast on the main thread.
  • The response body is closed via body?.use { … }, and also when the activity is already destroyed and the coroutine never starts (a0d9a78).
  • The decode/save part is extracted into decodeAvatarToFile and covered by PickImageTest.

…tests

Without @config the runner picks the target SDK (36) and has to download a
second android-all jar. On CI that download failed with an SSLException,
so the class failed with initializationError before any test ran.

Signed-off-by: Krainov Gleb <krajnov.g@kontentplus.ru>
Assisted-by: Claude-Code:claude-opus-5-5
@mahibi
mahibi merged commit 03f77d4 into nextcloud:master Oct 15, 2026
16 of 19 checks passed
@AndyScherzinger AndyScherzinger added this to the 25.1.0 milestone Oct 15, 2026

@rapterjet2004 rapterjet2004 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, all failure paths now tell the user, and launchClosing covering the case where the activity is destroyed before the coroutine starts is a nice catch. Tiny optional nit: decodeAvatarToFile logs with a hardcoded "PickImage" tag instead of a shared TAG constant.

@ToteMeiSter

Copy link
Copy Markdown
Contributor Author

Thanks! Follow-up for the TAG nit: #6912.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants