Repository navigation
Fix redaction running debug apps out of memory; opt-in field masking; one-finger edge swipe - #28
Merged
Merged
Conversation
… one-finger edge swipe Redaction crash - Kotlin's Regex.replace creates a new Matcher for every match, and on Android each Matcher copies the whole input into native memory. Masking a large GraphQL body made thousands of 500 KB copies, which aborted debug apps (CheckJNI) or got them killed for low memory. - NetworkRedaction now uses one Matcher per body and skips bodies that contain none of the field names; NetworkLogger.complete masks once, outside the StateFlow update that can retry. - Emulator stress test (4 threads x 5 bodies of 240K chars): 7.1 s per body, 703 MB native heap and a LOW_MEMORY kill before; 27-124 ms and 21.6 MB after. Masking - NetworkLogger.redactedFields is empty by default; auth, cookie, API-key and CSRF headers are still masked. NetworkLogger.DEFAULT_REDACTED_FIELDS turns field masking back on. Gestures - DeckGestures(oneFingerSwipe = true) opens the drawer with a one-finger swipe in from its edge (off by default); a 200dp strip of that edge is excluded from the system back gesture while the drawer is closed. The old DeckGestures constructor and copy are kept as hidden overloads.
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.
Why
A StockX debug build aborted in
NetworkRedaction.body(JNI DETECTED ERROR→Runtime aborting) while DevDeck's OkHttp interceptor masked a GraphQL response.Kotlin's
Regex.replacecallsmatcher.pattern().matcher(input)for every match (MatcherMatchResult.next, kotlin-stdlib 2.2.21). On Android each newMatchercopies the whole input into native memory through ICU, so a 240K-character body with thousands of JSON strings made thousands of ~500 KB copies. When ICU's allocation failed it raisedOutOfMemoryErrorand then calledFindClasswith that exception pending, which CheckJNI (on in debug builds) turns into an abort.What
Redaction
NetworkRedactionuses onejava.util.regex.Matcherper body, and skips the regex entirely when a body contains none of the field names (URL-encoded bodies still get the full pass).NetworkLogger.completemasks once, before theStateFlowupdate, instead of inside its retry lambda.NetworkLogger.redactedFieldsis empty by default. Auth, cookie, API-key and CSRF headers are still masked.NetworkLogger.DEFAULT_REDACTED_FIELDSturns field masking back on.One-finger edge swipe
DeckGestures(oneFingerSwipe = true): one finger swiping in from the drawer's edge (within 24dp) opens it. Off by default; the two-finger swipe is unchanged and each can be turned on or off.Compatibility
The old
DeckGesturesconstructor andcopyare kept as hidden overloads. Changing the masking default is a behaviour change, noted in the CHANGELOG.Checks
ktlintCheck lintDebug lintRelease assembleRelease testDebugUnitTest apiCheck :sample:assembleQapass locally.New tests: a 240K-character body with thousands of secrets, untouched bodies without secret names, URL-encoded field names, and the edge swipe tracker (both sides, start away from the edge, vertical drags, second finger, wrong direction).
Emulator stress test (temporary button, not committed; 4 threads × 5 bodies of 240K characters):
LOW_MEMORY)Emulator: with the one-finger option on, a swipe in from the middle of the right edge opened the drawer and a swipe starting mid-screen didn't; with it off, the edge swipe did nothing and the app stayed in front. Only the
DevDeckHostpath was tried on the emulator; theDevDeck.installpath shares the tracker, which has unit tests.🤖 Generated with Claude Code