SecureWindowPolicy.kt

2.0 KB · raw

1package com.peachpasswords.ui.components23import android.view.Window4import android.view.WindowManager5import java.util.WeakHashMap67/**8 * The only owner of [WindowManager.LayoutParams.FLAG_SECURE] transitions.9 *10 * Release activities install a permanent policy and therefore no later11 * composable can accidentally clear the activity-wide protection. Debug-only12 * secret screens take reference-counted leases so nested effects cannot clear13 * the flag while another secret screen is still composed. Window instances are14 * weakly keyed because their lifecycle owns the actual resources.15 */16internal object SecureWindowPolicy {17    private data class State(18        var leases: Int = 0,19        var userSecure: Boolean = true,20    )2122    private val states = WeakHashMap<Window, State>()2324    private fun evaluate(window: Window, state: State) {25        if (state.userSecure || state.leases > 0) {26            window.setFlags(27                WindowManager.LayoutParams.FLAG_SECURE,28                WindowManager.LayoutParams.FLAG_SECURE,29            )30        } else {31            window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)32        }33    }3435    /** Set the user's screenshot preference for this window. */36    fun setUserSecure(window: Window, secure: Boolean) {37        synchronized(states) {38            val state = states.getOrPut(window) { State() }39            state.userSecure = secure40            evaluate(window, state)41        }42    }4344    /** Acquire one debug/composable lease for a window. */45    fun acquire(window: Window) {46        synchronized(states) {47            val state = states.getOrPut(window) { State() }48            state.leases++49            evaluate(window, state)50        }51    }5253    /** Release one lease; re-evaluates the flag. */54    fun release(window: Window) {55        synchronized(states) {56            val state = states[window] ?: return57            if (state.leases > 0) state.leases--58            evaluate(window, state)59        }60    }61}