wordpress-mobile / wordpress-mobile/GutenbergKit
Android: requestLatestContent() lacks threading contract
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29
- Forks
- 6
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
Summary
requestLatestContent() in GutenbergView.kt is a @JavascriptInterface method that calls LatestContentProvider.getLatestContent() on the WebView's JavaBridge thread — not the main thread. However, neither the method nor the LatestContentProvider interface documents this threading behavior.
This is the only @JavascriptInterface method in GutenbergView that returns a value to JavaScript. Every other @JavascriptInterface method that touches app state uses handler.post { } to dispatch to the main thread, but requestLatestContent() cannot do this without losing its return value.
The problem
Host app implementors of LatestContentProvider.getLatestContent() will naturally access main-thread-only state (e.g., Android ViewModel/LiveData, repositories with @MainThread contracts). Without documentation or annotations, they have no indication that getLatestContent() runs off the main thread.
For comparison, the iOS equivalent in EditorViewController.swift explicitly dispatches to the main actor:
await MainActor.run { ... }
Suggested improvements
-
Document the threading contract — Add a
@WorkerThreadannotation (or equivalent KDoc) toLatestContentProvider.getLatestContent()so implementors know they're responsible for thread safety. -
(Optional) Handle thread dispatch internally — Since
requestLatestContent()already runs on the JavaBridge thread (a background thread), GutenbergKit could internally use aCountDownLatchor similar mechanism to read from the main thread and return the result synchronously:@JavascriptInterface fun requestLatestContent(): String? { var content: LatestContent? = null val latch = CountDownLatch(1) handler.post { content = latestContentProvider?.getLatestContent() latch.countDown() } latch.await() // serialize and return }This would make the API safe by default, matching the iOS behavior.
Context
Found during review of wordpress-mobile/WordPress-Android#22774. The WordPress-Android implementation accesses EditPostRepository.title/.content (which have no synchronization) directly from the JavaBridge thread.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with requestLatestContent() in GutenbergView.kt and the LatestContentProvider interface, then trace how the JavaBridge thread invokes the provider. Clarify whether the intended change is an annotation/KDoc contract or internal main-thread dispatch; done means the chosen threading behavior is explicit to host-app implementors and consistent with the API’s synchronous return value.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- documentation, mobile
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100