Приватные уведомления на локскрине + откат биопривязки (требование владельца: звонки/push при блокировке)
Владелец: входящие звонки и push должны работать при заблокированном телефоне.
- Биопривязка app password ОТКЛОНЕНА (вариант А): блокировала приём звонка без
разблокировки. Откачена из main (сохранена на ветке wip/biometric-binding).
Пароль остаётся под Keystore AES-256-GCM (п.3) — работает в фоне.
- Приватность локскрина: сообщения и звонки → VISIBILITY_PRIVATE + generic
public-версия ('Новое сообщение'/'Входящий звонок'); канал lockscreenVisibility=PRIVATE.
Полный контент — после разблокировки. Push приходит plaintext, для показа/звонка
пароль не нужен → звонки звонят и пуши приходят при блокировке.
Проверено сборкой: assembleRelease BUILD SUCCESSFUL, APK 53 МБ.
This commit is contained in:
@@ -241,7 +241,8 @@ object F7IncomingCallQueue {
|
||||
.setStyle(callStyle)
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
|
||||
.setPublicVersion(genericCallPublic(context, intents.preview))
|
||||
.setOngoing(true)
|
||||
.setAutoCancel(false)
|
||||
.setOnlyAlertOnce(true)
|
||||
@@ -282,7 +283,8 @@ object F7IncomingCallQueue {
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText(body))
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
|
||||
.setPublicVersion(genericCallPublic(context, intents.preview))
|
||||
.setOngoing(true)
|
||||
.setAutoCancel(false)
|
||||
.setOnlyAlertOnce(true)
|
||||
@@ -304,6 +306,21 @@ object F7IncomingCallQueue {
|
||||
?: throw IllegalStateException("NotificationManager unavailable")
|
||||
}
|
||||
|
||||
/**
|
||||
* Обезличенная (public) версия уведомления звонка для локскрина: показывает лишь «Входящий
|
||||
* звонок» без имени звонящего/комнаты (минимум информации, решение владельца). Полное имя —
|
||||
* в полноэкранном UI звонка/после разблокировки. Full-screen intent работает независимо от visibility.
|
||||
*/
|
||||
private fun genericCallPublic(context: Context, preview: PendingIntent): android.app.Notification =
|
||||
NotificationCompat.Builder(context, F7NotificationChannels.CALLS)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_phone_call)
|
||||
.setContentTitle("F7cloud")
|
||||
.setContentText("Входящий звонок")
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
.setContentIntent(preview)
|
||||
.build()
|
||||
|
||||
private fun resolveJoinUrl(context: Context, call: PendingCall): String? {
|
||||
val raw = call.acceptUrl?.takeIf { it.isNotBlank() }
|
||||
?: AuthStore(context).load()?.let { session ->
|
||||
|
||||
@@ -48,7 +48,10 @@ object F7NotificationChannels {
|
||||
setSound(sound, soundAttrs)
|
||||
}
|
||||
setShowBadge(true)
|
||||
lockscreenVisibility = android.app.Notification.VISIBILITY_PUBLIC
|
||||
// Приватно на локскрине: система покажет public-версию (generic), а не полный
|
||||
// контент (минимум информации, решение владельца). Public-версия задаётся
|
||||
// per-notification в F7PushNotificationHelper / F7IncomingCallQueue.
|
||||
lockscreenVisibility = android.app.Notification.VISIBILITY_PRIVATE
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -49,6 +49,21 @@ object F7PushNotificationHelper {
|
||||
}
|
||||
val iconRes = context.applicationInfo.icon.takeIf { it != 0 }
|
||||
?: android.R.drawable.stat_notify_chat
|
||||
// На локскрине — ОБЕЗЛИЧЕННАЯ версия (минимум информации, решение владельца): отправитель
|
||||
// и текст не утекают на заблокированном экране. Полный контент — после разблокировки.
|
||||
val genericText = when (type) {
|
||||
"chat", "room", "message" -> "Новое сообщение"
|
||||
"call" -> "Входящий звонок"
|
||||
else -> "Новое уведомление"
|
||||
}
|
||||
val publicVersion = NotificationCompat.Builder(context, channel)
|
||||
.setSmallIcon(iconRes)
|
||||
.setContentTitle("F7cloud")
|
||||
.setContentText(genericText)
|
||||
.setAutoCancel(true)
|
||||
.setPriority(priority)
|
||||
.setContentIntent(pending)
|
||||
.build()
|
||||
val notification = NotificationCompat.Builder(context, channel)
|
||||
.setSmallIcon(iconRes)
|
||||
.setContentTitle(title)
|
||||
@@ -56,6 +71,8 @@ object F7PushNotificationHelper {
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText(body))
|
||||
.setAutoCancel(true)
|
||||
.setPriority(priority)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
|
||||
.setPublicVersion(publicVersion)
|
||||
.setContentIntent(pending)
|
||||
.build()
|
||||
manager.notify((System.currentTimeMillis() % Int.MAX_VALUE).toInt(), notification)
|
||||
|
||||
Reference in New Issue
Block a user