On low-RAM devices under sustained memory pressure, the Android OS can OOM-kill the WebView renderer process.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ZemerTeam/zemer-cipher/llms.txt
Use this file to discover all available pages before exploring further.
RendererRecoveryPolicy tracks consecutive renderer deaths and opens a short backoff window after repeated failures, preventing the library from wasting time re-parsing the ~2.8 MB player JS when a fresh renderer would immediately be killed again.
Package: com.zemer.cipher
The policy is pure Kotlin with no Android dependencies, making it fully unit-testable with any monotonic clock source.
Constructor
Number of consecutive renderer deaths that must occur before the backoff window is armed. Defaults to
DEFAULT_MAX_CONSECUTIVE_FAILURES (3). After this many consecutive failures, shouldAttempt returns false until the backoff window expires.Duration of the backoff window in milliseconds. Defaults to
DEFAULT_BACKOFF_MS (60 000 ms = 1 minute). The window starts when consecutiveFailures reaches maxConsecutiveFailures inside onFailure.Companion Constants
| Constant | Value | Description |
|---|---|---|
DEFAULT_MAX_CONSECUTIVE_FAILURES | 3 | Default threshold of consecutive renderer deaths before backoff. |
DEFAULT_BACKOFF_MS | 60_000L | Default backoff window duration (1 minute). |
Properties
consecutiveFailures
onFailure; reset to 0 by onSuccess.
Methods
shouldAttempt
true if creating or using a WebView should be attempted right now. Returns false only when both of the following are true:
consecutiveFailures >= maxConsecutiveFailures(the failure threshold has been reached), and- the current time
nowMsis still within the backoff window (i.e.nowMs < backoffUntilMs).
true again, allowing exactly one attempt. If that attempt fails, onFailure re-arms the window immediately.
Current monotonic clock value in milliseconds. Pass
SystemClock.elapsedRealtime() in production code.onFailure
consecutiveFailures. When consecutiveFailures reaches maxConsecutiveFailures, arms the backoff window by setting backoffUntilMs = nowMs + backoffMs.
Current monotonic clock value in milliseconds at the time of the failure. Pass
SystemClock.elapsedRealtime() in production code.onSuccess
consecutiveFailures = 0 and clears the backoff window (backoffUntilMs = 0). Call this after any successful sig deobfuscation or n-transform completes without a CipherRendererGoneException.
Usage Example
The backoff window is deliberately short (1 minute by default) and half-open: once the window expires, one attempt is always allowed regardless of
consecutiveFailures. This design keeps the cipher WebView as the primary deciphering path, since fallback clients (NewPipe extractor, alternate YouTube clients) are generally less reliable. A single successful attempt fully resets the policy; another failure re-arms the window immediately.