Skip to content

Commit 7277c78

Browse files
committed
Fix Archive closing right after Face ID unlock
restoreArchivePrivacyOnBecomeActive used isLockActive, which is true while unlocked, so become-active after biometric resign popped the just-opened Archive. Only dismiss when still locked; suppress background relock during LocalAuth for Archive unlock so resign cannot clear reveal mid-prompt. Co-authored-by: D3C0Y <decoder-dev@users.noreply.github.com>
1 parent 0669af1 commit 7277c78

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

‎submodules/ChatListUI/Sources/ArchiveLockHelpers.swift‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,11 @@ public func prepareArchivePrivacyOnResignActive(context: AccountContext) {
200200

201201
/// Drop remaining Archive surfaces, then remove the switcher cover only once they are gone.
202202
public func restoreArchivePrivacyOnBecomeActive(context: AccountContext) {
203-
if ArchiveLockSession.shared.isLockActive {
203+
// Only sweep when the session is *locked*. `isLockActive` is also true while unlocked
204+
// (passwordConfigured || unlocked), and Face ID / Touch ID for Archive unlock resigns
205+
// active then becomes active again — dismissing here would pop the Archive that just
206+
// opened after a successful biometric unlock.
207+
if ArchiveLockSession.shared.isPasswordConfigured && !ArchiveLockSession.shared.isUnlocked {
204208
dismissOpenArchiveControllers(from: archiveNavigationController(context: context), context: context)
205209
}
206210
removeArchiveLockSwitcherCover(context: context)
@@ -434,8 +438,12 @@ public func ensureArchiveUnlocked(
434438
// set (checked above) and the user opted in per-account. A cancel/failure always
435439
// falls through to the password prompt — never a dead end.
436440
if settings.useBiometrics, LocalAuth.biometricAuthentication != nil {
441+
// Biometric UI resigns active; suppress Archive background-relock for that window
442+
// so Face ID does not clear reveal / dismiss the folder mid-unlock.
443+
ArchiveLockSession.shared.beginSuppressBackgroundRelock()
437444
let _ = (LocalAuth.auth(reason: ArchiveLockLocalizedString.biometricReason)
438445
|> deliverOnMainQueue).start(next: { success, _ in
446+
ArchiveLockSession.shared.endSuppressBackgroundRelock()
439447
if success {
440448
// Same reset the password path does on success. Both outcomes mean the owner
441449
// proved who they are, and the counter throttles guessing, not the owner — but

‎submodules/TelegramUIPreferences/Sources/ChatArchiveSettings.swift‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ public final class ArchiveLockSession {
128128
/// registered after `bindBackgroundRelock` (first-wins) has already claimed the slot.
129129
private var willRelockHandlerValue: (() -> Void)?
130130
private var didBecomeActiveHandlerValue: (() -> Void)?
131+
/// >0 while Archive biometric unlock is in progress. Face ID/Touch ID resigns active and
132+
/// would otherwise `relock()` mid-prompt (clear reveal + schedule dismiss of the folder
133+
/// we are about to open).
134+
private var suppressBackgroundRelockCount: Int = 0
131135
private var collapseGeneration: Int = 0
132136
private let relockedPipe = ValuePipe<Void>()
133137
private let revealedPromise = ValuePromise<Bool>(false, ignoreRepeated: true)
@@ -385,6 +389,18 @@ public final class ArchiveLockSession {
385389
return true
386390
}
387391

392+
public func beginSuppressBackgroundRelock() {
393+
self.lock.lock()
394+
self.suppressBackgroundRelockCount += 1
395+
self.lock.unlock()
396+
}
397+
398+
public func endSuppressBackgroundRelock() {
399+
self.lock.lock()
400+
self.suppressBackgroundRelockCount = max(0, self.suppressBackgroundRelockCount - 1)
401+
self.lock.unlock()
402+
}
403+
388404
/// App-switcher cover, installed from TelegramUI where `Window1` is available. Invoked on
389405
/// the main queue immediately before `relock()` so the snapshot still sees `isUnlocked`.
390406
public var willRelockHandler: (() -> Void)? {
@@ -518,9 +534,18 @@ public final class ArchiveLockSession {
518534
didBecomeActive?()
519535
self?.didBecomeActiveHandler?()
520536
} else {
537+
guard let self else {
538+
return
539+
}
540+
self.lock.lock()
541+
let suppressed = self.suppressBackgroundRelockCount > 0
542+
self.lock.unlock()
543+
if suppressed {
544+
return
545+
}
521546
willRelock?()
522-
self?.willRelockHandler?()
523-
self?.relock()
547+
self.willRelockHandler?()
548+
self.relock()
524549
}
525550
})
526551
self.lock.lock()

0 commit comments

Comments
 (0)