Hide "sensitive" views from the App Switcher
This commit is contained in:
parent
6be8862bdb
commit
30431a6354
@ -369,13 +369,14 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var screenLockUI = ScreenLockUI(appReadiness: appReadiness)
|
||||
|
||||
private func configureGlobalUI(in window: UIWindow) {
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
let windowManager = AppEnvironment.shared.windowManagerRef
|
||||
|
||||
Theme.setupSignalAppearance()
|
||||
|
||||
screenLockUI.setupWithRootWindow(window)
|
||||
AppEnvironment.shared.windowManagerRef.setupWithRootWindow(window, screenBlockingWindow: screenLockUI.screenBlockingWindow)
|
||||
windowManager.setupWithRootWindow(window, screenBlockingWindow: screenLockUI.screenBlockingWindow)
|
||||
screenLockUI.startObserving()
|
||||
}
|
||||
|
||||
@ -1770,15 +1771,23 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
}
|
||||
let isVideo = isVideoCall(intent)
|
||||
|
||||
Task { @MainActor [appReadiness, screenLockUI] in
|
||||
Task { @MainActor [appReadiness] in
|
||||
do {
|
||||
try await appReadiness.waitForAppReady()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
let callService = AppEnvironment.shared.callService!
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
let tsAccountManager = DependenciesBridge.shared.tsAccountManager
|
||||
|
||||
do {
|
||||
try await screenLockUI.waitForScreenUnlockThrowingPrevious()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
let tsAccountManager = DependenciesBridge.shared.tsAccountManager
|
||||
guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else {
|
||||
Logger.warn("Ignoring user activity; not registered.")
|
||||
return
|
||||
@ -1796,7 +1805,6 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// * It can be received if the user taps the "video" button for a contact
|
||||
// in the contacts app. If so, the correct response is to try to initiate a
|
||||
// new call to that user - unless there is another call in progress.
|
||||
let callService = AppEnvironment.shared.callService!
|
||||
if let currentCall = callService.callServiceState.currentCall {
|
||||
if isVideo, case .individual = currentCall.mode, currentCall.mode.matches(callTarget) {
|
||||
Logger.info("Upgrading existing call to video")
|
||||
@ -1933,12 +1941,18 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
|
||||
withCompletionHandler completionHandler: @escaping () -> Void,
|
||||
) {
|
||||
let startDate = MonotonicDate()
|
||||
Task { @MainActor [appReadiness, screenLockUI] () -> Void in
|
||||
Task { @MainActor [appReadiness] () -> Void in
|
||||
defer { completionHandler() }
|
||||
|
||||
try await self.appReadiness.waitForAppReady()
|
||||
do {
|
||||
try await self.appReadiness.waitForAppReady()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
let backgroundMessageFetcherFactory = DependenciesBridge.shared.backgroundMessageFetcherFactory
|
||||
|
||||
let backgroundMessageFetcher = backgroundMessageFetcherFactory.buildFetcher()
|
||||
// So that we open up a connection for replies.
|
||||
await backgroundMessageFetcher.start()
|
||||
|
||||
@ -22,12 +22,12 @@ public class AppEnvironment: NSObject {
|
||||
@MainActor
|
||||
var ownedObjects = [AnyObject]()
|
||||
|
||||
let cvAudioPlayerRef: CVAudioPlayer
|
||||
let deviceTransferServiceRef: DeviceTransferService
|
||||
let pushRegistrationManagerRef: PushRegistrationManager
|
||||
|
||||
let cvAudioPlayerRef = CVAudioPlayer()
|
||||
let speechManagerRef = SpeechManager()
|
||||
let windowManagerRef = WindowManager()
|
||||
let screenLockUI: ScreenLockUI
|
||||
let speechManagerRef: SpeechManager
|
||||
let windowManagerRef: WindowManager
|
||||
|
||||
private(set) var appIconBadgeUpdater: AppIconBadgeUpdater!
|
||||
private(set) var avatarHistoryManager: AvatarHistoryManager!
|
||||
@ -44,8 +44,12 @@ public class AppEnvironment: NSObject {
|
||||
private var registrationIdMismatchManager: RegistrationIdMismatchManager!
|
||||
|
||||
init(appReadiness: AppReadiness, deviceTransferService: DeviceTransferService) {
|
||||
self.cvAudioPlayerRef = CVAudioPlayer()
|
||||
self.deviceTransferServiceRef = deviceTransferService
|
||||
self.screenLockUI = ScreenLockUI(appReadiness: appReadiness)
|
||||
self.pushRegistrationManagerRef = PushRegistrationManager(appReadiness: appReadiness)
|
||||
self.speechManagerRef = SpeechManager()
|
||||
self.windowManagerRef = WindowManager()
|
||||
|
||||
super.init()
|
||||
|
||||
|
||||
@ -77,6 +77,9 @@ class BackupRecordKeyViewController: OWSViewController, OWSNavigationChildContro
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
screenLockUI.sensitiveContentDidLoad(inViewController: self)
|
||||
|
||||
view.backgroundColor = .Signal.groupedBackground
|
||||
|
||||
if let onBackPressedBlock {
|
||||
|
||||
@ -51,6 +51,9 @@ class EnterAccountEntropyPoolViewController: OWSViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
screenLockUI.sensitiveContentDidLoad(inViewController: self)
|
||||
|
||||
view.backgroundColor = colorConfig.background
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: CommonStrings.nextButton,
|
||||
|
||||
@ -25,6 +25,9 @@ class PaymentsViewPassphraseGridViewController: OWSViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let screenLockUI = AppEnvironment.shared.screenLockUI
|
||||
screenLockUI.sensitiveContentDidLoad(inViewController: self)
|
||||
|
||||
title = OWSLocalizedString(
|
||||
"SETTINGS_PAYMENTS_VIEW_PASSPHRASE_TITLE",
|
||||
comment: "Title for the 'view payments passphrase' view of the app settings.",
|
||||
|
||||
@ -124,7 +124,7 @@ class ScreenLockUI {
|
||||
self.appReadiness = appReadiness
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
// MARK: -
|
||||
|
||||
func setupWithRootWindow(_ rootWindow: UIWindow) {
|
||||
AssertIsOnMainThread()
|
||||
@ -180,6 +180,21 @@ class ScreenLockUI {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Sensitive Content
|
||||
|
||||
/// Tracks view controllers displaying "sensitive content" that should be
|
||||
/// hidden from the App Switcher.
|
||||
private var sensitiveContentViewControllers: WeakArray<UIViewController> = []
|
||||
|
||||
@MainActor
|
||||
func sensitiveContentDidLoad(inViewController viewController: UIViewController) {
|
||||
if sensitiveContentViewControllers.contains(where: { $0 === viewController }) {
|
||||
return
|
||||
}
|
||||
|
||||
sensitiveContentViewControllers.append(viewController)
|
||||
}
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
private func updateScreenBlockingWindowWithUIState(_ uiState: ScreenLockViewController.UIState) {
|
||||
@ -251,7 +266,16 @@ class ScreenLockUI {
|
||||
return .none
|
||||
}
|
||||
|
||||
guard SSKEnvironment.shared.preferencesRef.isScreenSecurityEnabled else {
|
||||
// Cull any "sensitive content" view controllers that aren't actually
|
||||
// presenting content. (Their presence here may suggest a retain cycle.)
|
||||
sensitiveContentViewControllers.removeAll(where: { viewController in
|
||||
!viewController.isViewLoaded || viewController.view.window == nil
|
||||
})
|
||||
|
||||
guard
|
||||
SSKEnvironment.shared.preferencesRef.isScreenSecurityEnabled
|
||||
|| sensitiveContentViewControllers.elements.count > 0
|
||||
else {
|
||||
return .none
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,16 @@ public struct WeakArray<Element> {
|
||||
}
|
||||
}
|
||||
|
||||
public func contains(where predictate: (Element) -> Bool) -> Bool {
|
||||
return array.contains { weakElement in
|
||||
if let element = weakElement.value, predictate(element) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func cullExpired() {
|
||||
array.removeAll { weakBox in
|
||||
weakBox.value == nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user