fix(android): isolate logger locale so it can't corrupt the host app#39
Open
mibrahimdev wants to merge 1 commit into
Open
fix(android): isolate logger locale so it can't corrupt the host app#39mibrahimdev wants to merge 1 commit into
mibrahimdev wants to merge 1 commit into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #38.
Problem
Opening the Sharingan logger (
SharinganActivity, launched from the capture notification withFLAG_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
SharinganActivityis a plainComponentActivitythat 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-globalLocale/LocaleListdefault 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:
SharinganActivity) —attachBaseContextpins anen/LTRConfigurationvia the non-mutatingcreateConfigurationContext(neverresources.updateConfiguration). A red test provedcreateConfigurationContext(en)resetsLocaleList.getDefault()to English, so the activity now snapshots the host'sLocaleListand restores it — right after the config context, and again inonDestroy— leaving the host untouched.SharinganScreenContent) — wraps the stateless body inCompositionLocalProvider(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
:sharinganUI suite (8),CaptureNotificationE2eTest,:sharingan:testDebugUnitTest, andiosSimulatorArm64Test.Notes
publicAPI;apiCheckparity unaffected.🤖 Generated with Claude Code