Skip to content

fix(android): isolate logger locale so it can't corrupt the host app#39

Open
mibrahimdev wants to merge 1 commit into
developfrom
fix/38-logger-locale-leak
Open

fix(android): isolate logger locale so it can't corrupt the host app#39
mibrahimdev wants to merge 1 commit into
developfrom
fix/38-logger-locale-leak

Conversation

@mibrahimdev

Copy link
Copy Markdown
Owner

Closes #38.

Problem

Opening the Sharingan logger (SharinganActivity, launched from the capture notification with FLAG_ACTIVITY_NEW_TASK) from a host app using per-app locales set to Arabic (RTL) rendered the logger as English text in an RTL frame and — worse — permanently corrupted the host: after closing the logger, the host app was stuck in English text with RTL layout.

Root cause

SharinganActivity is a plain ComponentActivity that neither pinned its own locale nor guarded the process-global one. On API 33+ the framework applied the host's per-app locale (ar → RTL) to the logger, and its config handling flipped the process-global Locale/LocaleList default to English, which leaked back to the host.

Fix

The logger is a locale-neutral surface: always English + LTR, and it must never read or mutate the host's locale. Two layers:

  • Activity (SharinganActivity)attachBaseContext pins an en/LTR Configuration via the non-mutating createConfigurationContext (never resources.updateConfiguration). A red test proved createConfigurationContext(en) resets LocaleList.getDefault() to English, so the activity now snapshots the host's LocaleList and restores it — right after the config context, and again in onDestroy — leaving the host untouched.
  • Compose (SharinganScreenContent) — wraps the stateless body in CompositionLocalProvider(LocalLayoutDirection provides Ltr) so the frame is LTR on every platform (including iOS, where the activity mechanism doesn't exist) and previews inherit it.

Tests

New instrumented regression LoggerLocaleLeakTest (@SdkSuppress(33)): pins the process to Arabic, opens/closes the logger, asserts the logger is LTR while open and every process-global locale knob (Locale.getDefault(), LocaleList.getDefault()) is still Arabic after.

Verified red→green on an API 34 emulator. Green: the new test, the :sharingan UI suite (8), CaptureNotificationE2eTest, :sharingan:testDebugUnitTest, and iosSimulatorArm64Test.

Notes

  • No new public API; apiCheck parity unaffected.
  • 3 files changed; no gradle/version-catalog changes.
  • Independently reviewed on two axes (locale-mechanism correctness + quality/conventions); all findings applied.

🤖 Generated with Claude Code

Opening the Sharingan logger from a host that uses per-app locales
(e.g. AppCompat set to Arabic/RTL) rendered the logger in an RTL frame
and, worse, permanently corrupted the host: after closing the logger the
host was stuck in English text with RTL layout (issue #38).

Root cause: SharinganActivity is a plain ComponentActivity that neither
pins its own locale nor guards the process-global one. On API 33+ the
framework applied the host's per-app locale (ar -> RTL) to the logger,
and the logger's config handling flipped the process-global
Locale/LocaleList default to English, which leaked back to the host.

The logger is a locale-neutral surface: always English + LTR, and it must
never read or mutate the host's locale. Two-layer fix:

- Activity: attachBaseContext pins an en/LTR Configuration via the
  non-mutating createConfigurationContext (never resources.updateConfiguration).
- Compose: the stateless SharinganScreenContent forces
  LocalLayoutDirection = Ltr around its whole body, so the frame is LTR on
  every platform (including iOS) and in Studio previews.

The global-locale guard was needed: an instrumented test proved that
createConfigurationContext(en) resets LocaleList.getDefault() to English.
SharinganActivity now snapshots the host's LocaleList in attachBaseContext
and restores it (right after, and again in onDestroy), leaving the host's
locale untouched.

Verified red->green on an API 34 emulator with a new instrumented test that
pins the process to Arabic, opens/closes the logger, and asserts the logger
is LTR while open and every process-global JVM locale default is still
Arabic after. The test is @SdkSuppress(minSdkVersion = 33) since it drives
the API 33+ LocaleManager.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

[Bug] Opening Sharingan logger screen resets app locale to English while preserving RTL layout direction

1 participant