wordpress-mobile / wordpress-mobile/GutenbergKit
Enable strict StrictMode in the Android demo app
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29
- Forks
- 6
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
Context
The demo app at android/app/ (package com.example.gutenbergkit) is the project's reference integrator and the natural canary for library-side regressions. Today it doesn't configure StrictMode at all, so disk I/O on the main thread, leaked closables, registration leaks, etc. introduced inside the library go unnoticed during development and only surface in third-party host apps that do run StrictMode.
This is a demo-app-only change — the library itself stays untouched. The goal is "if the library starts doing something StrictMode-bad, the demo catches it on the next dev build."
Scope
- In scope:
android/app/(the:appmodule). Configure StrictMode in the demo'sApplicationclass. - Out of scope:
android/Gutenberg/(the:Gutenberglibrary module). Do not addStrictMode.allowThreadDiskReads()suppressions to library code as part of this work — if you find violations there, those are bugs to fix or document, not silence here. - Debug builds only: gate the entire setup behind
if (BuildConfig.DEBUG). Release builds must not configure StrictMode.
Phased approach
Don't go straight to penaltyDeath(). Two PRs, in this order:
Phase 1 — penaltyLog() everywhere
-
Find or create the demo's
Applicationsubclass. Search forclass GutenbergKitApplicationinandroid/app/src/main/java/. -
In
onCreate(), aftersuper.onCreate(), add a debug-only StrictMode setup:if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build() ) } -
Verify the manifest registers the
Applicationsubclass viaandroid:name. IfGutenbergKitApplicationisn't yet registered inandroid/app/src/main/AndroidManifest.xml, register it. -
Build, run the demo on a connected device, and exercise the full demo flow:
- Launch the app
- Tap Bundled Editor → site preparation → enable Native Inserter → load editor
- Open the block inserter sheet (the + button)
- Tap each category chip
- Open the photos rationale (if first run), tap Allow / Reject / Try Again paths
- Pick a photo via the Photos tile
- Tap Camera tile
- Dismiss and reopen the sheet a few times
- Type into the search field
- Use the overflow menu's "Reset Photo Permissions Prompts"
- Background the app; resume
-
Capture all StrictMode violations from logcat (filter on tag
StrictMode). Expected violations to see, based on prior review of #479:- One
DiskReadViolationon first inserter open, fromgetSharedPreferences("gbk_inserter")inRecentImages.kt'shasPromptedForPhotos. This is the only one the recent media-strip work introduces; the read is sub-millisecond and one-time per process. Document it; don't fix it in this PR. - Possibly older violations from the editor's WebView setup, asset loading, network monitoring registration, and so on. Catalogue what you find.
- One
-
Add a new entry to
docs/code/(e.g.docs/code/strictmode.md) that:- Documents the configuration.
- Lists the known violations the demo currently surfaces (with file:line references).
- Names which are intentional (permit) vs. which are tracked for fix in follow-up issues.
- References the path to
penaltyDeath(Phase 2).
-
Acceptance: demo app builds, installs, runs without crashing. Logcat shows StrictMode violations. None are unexplained — every violation is either documented or referenced by a tracking issue.
Phase 2 (separate follow-up PR) — penaltyDeath()
After Phase 1's documented violations have been fixed or explicitly permitted, switch the penalty:
.penaltyDeath()
This will crash the demo on any new violation, ensuring future library changes can't quietly regress. Reviewers note: this depends on Phase 1 having addressed every documented violation, so don't merge Phase 2 until that work is in.
Implementation notes
detectAll()is the right starting point. It's a superset that includesdetectDiskReads,detectDiskWrites,detectNetwork,detectCustomSlowCalls,detectResourceMismatches,detectUnbufferedIo, and (onVmPolicy)detectLeakedClosableObjects,detectLeakedRegistrationObjects,detectActivityLeaks,detectFileUriExposure,detectCleartextNetwork,detectContentUriWithoutPermission,detectUntaggedSockets,detectImplicitDirectBoot,detectCredentialProtectedWhileLocked,detectIncorrectContextUse,detectUnsafeIntentLaunch. Some of these (detectCleartextNetwork,detectFileUriExposure) may already be tripped by demo-only test paths — note those explicitly.Application.onCreate()is the right place, notActivity.onCreate(). StrictMode should be set as early as possible in process startup so it covers everything that follows.- Don't enable
penaltyDialog(). It interrupts manual testing without adding signal. Stick to log + (eventually) death. - Don't enable
penaltyDeath()onVmPolicyeither, in Phase 2. VM violations likeLeakedClosableObjecthappen during GC and can crash the app at unpredictable times unrelated to the offending code path.penaltyLog()for VmPolicy is sufficient. - The demo currently has at least one prefs read on inserter open (cited above). That's a known violation introduced in #479 and is sub-millisecond, one-time per process. Either document-and-permit it via
StrictMode.allowThreadDiskReads().resetAfterinside the library helper, or accept the logcat line as cost-of-doing-business and document it. Don't apply a permit at the demo level — that hides the violation from future hosts who would also see it.
Files to touch (expected)
android/app/src/main/java/com/example/gutenbergkit/GutenbergKitApplication.kt— add the StrictMode setup.android/app/src/main/AndroidManifest.xml— verify or addandroid:name=".GutenbergKitApplication"on the<application>element.docs/code/strictmode.md(new) — short doc per the structure above.
Out-of-scope but worth flagging in the PR description
- This work makes no library-side changes; if the catalogue surfaces real bugs in
:Gutenberg, file follow-up issues, don't fix them here. - Production builds are unaffected —
BuildConfig.DEBUGguard. - Phase 2 (
penaltyDeath) is its own PR.
Done when
- Phase 1 PR opens with the demo configured for
penaltyLog()on both policies. - The doc at
docs/code/strictmode.mdenumerates every violation the configured demo currently surfaces, each labelled either fix-tracked-in-#NNN or intentional-permit-because-X. - The author has manually run through the demo flow above with logcat open and captured the catalogue.
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 android/app/src/main/java/com/example/gutenbergkit/GutenbergKitApplication.kt and android/app/src/main/AndroidManifest.xml, then inspect the existing application entry point. Build and install the demo, exercise the listed editor and photo flows with logcat filtered for StrictMode, and record each violation. Done means the debug-only Phase 1 setup is present, the demo runs, and docs/code/strictmode.md explains every observed violation or links it to a tracking issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- documentation, mobile-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100