fix(app): secrets are kept out of screenshots and the recent apps
The recovery phrase, recovery codes and an authenticator's QR code and key now show inside a SecretScreen: on Android it holds FLAG_SECURE while it shows (through a channel each app's MainActivity answers, counting holds, as several may show at once; ScreenGuard.kt), so screenshots, screen recordings and the recents view don't get them; on iOS, which has no such flag, it covers them while the app isn't in front, so the app switcher's picture doesn't hold them (Dart-side, not checked on a device). Desktops do neither: a window loses focus whenever its person turns to a password manager. Todo's debug APK builds with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
3ca01915e2
commit
f3c3f7fb51
2 changed files with 509 additions and 180 deletions
|
|
@ -1,5 +1,12 @@
|
|||
package app.halkyon.todo
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
|
||||
class MainActivity : FlutterActivity()
|
||||
class MainActivity : FlutterActivity() {
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
// Secrets halkyon_app shows kept out of screenshots and recents.
|
||||
ScreenGuard.attach(this, flutterEngine.dartExecutor.binaryMessenger)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package app.halkyon.todo
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.WindowManager
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
/**
|
||||
* Keeps the window's content out of screenshots, screen recordings and the
|
||||
* recents view (FLAG_SECURE) while halkyon_app shows something secret: the
|
||||
* recovery phrase, recovery codes, an authenticator's key. Its SecretScreen
|
||||
* holds as each shows and releases as it goes; counted, as several may show
|
||||
* at once.
|
||||
*/
|
||||
object ScreenGuard {
|
||||
fun attach(activity: Activity, messenger: BinaryMessenger) {
|
||||
var holds = 0
|
||||
MethodChannel(messenger, "app.halkyon/screen_guard").setMethodCallHandler { call, result ->
|
||||
when (call.method) {
|
||||
"hold" -> {
|
||||
holds++
|
||||
activity.window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
result.success(null)
|
||||
}
|
||||
"release" -> {
|
||||
holds = maxOf(0, holds - 1)
|
||||
if (holds == 0) {
|
||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
result.success(null)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue