diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 1e44be3543..72f3b55784 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -904,7 +904,9 @@ private func extractAccountManagerState(records: AccountRecordsView map { ($0.0?.account, $0.1.map { ($0.0, $0.1.account) }) }, liveLocationPolling: liveLocationPolling, watchTasks: watchTasks, inForeground: applicationBindings.applicationInForeground, hasActiveAudioSession: self.hasActiveAudioSession.get(), notificationManager: notificationManager, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in + let wakeupManager = SharedWakeupManager(beginBackgroundTask: { name, expiration in application.beginBackgroundTask(withName: name, expirationHandler: expiration) }, endBackgroundTask: { id in application.endBackgroundTask(id) }, backgroundTimeRemaining: { application.backgroundTimeRemaining }, acquireIdleExtension: { + return applicationBindings.pushIdleTimerExtension() + }, activeAccounts: sharedContext.activeAccountContexts |> map { ($0.0?.account, $0.1.map { ($0.0, $0.1.account) }) }, liveLocationPolling: liveLocationPolling, watchTasks: watchTasks, inForeground: applicationBindings.applicationInForeground, hasActiveAudioSession: self.hasActiveAudioSession.get(), notificationManager: notificationManager, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in return sharedContext.accountUserInterfaceInUse(id) }) let sharedApplicationContext = SharedApplicationContext(sharedContext: sharedContext, notificationManager: notificationManager, wakeupManager: wakeupManager) diff --git a/submodules/TelegramUI/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Sources/ShareExtensionContext.swift index ed67e9a955..104c329fe4 100644 --- a/submodules/TelegramUI/Sources/ShareExtensionContext.swift +++ b/submodules/TelegramUI/Sources/ShareExtensionContext.swift @@ -33,7 +33,9 @@ private final class InternalContext { init(sharedContext: SharedAccountContextImpl) { self.sharedContext = sharedContext - self.wakeupManager = SharedWakeupManager(beginBackgroundTask: { _, _ in nil }, endBackgroundTask: { _ in }, backgroundTimeRemaining: { 0.0 }, activeAccounts: sharedContext.activeAccountContexts |> map { ($0.0?.account, $0.1.map { ($0.0, $0.1.account) }) }, liveLocationPolling: .single(nil), watchTasks: .single(nil), inForeground: inForeground.get(), hasActiveAudioSession: .single(false), notificationManager: nil, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in + self.wakeupManager = SharedWakeupManager(beginBackgroundTask: { _, _ in nil }, endBackgroundTask: { _ in }, backgroundTimeRemaining: { 0.0 }, acquireIdleExtension: { + return nil + }, activeAccounts: sharedContext.activeAccountContexts |> map { ($0.0?.account, $0.1.map { ($0.0, $0.1.account) }) }, liveLocationPolling: .single(nil), watchTasks: .single(nil), inForeground: inForeground.get(), hasActiveAudioSession: .single(false), notificationManager: nil, mediaManager: sharedContext.mediaManager, callManager: sharedContext.callManager, accountUserInterfaceInUse: { id in return sharedContext.accountUserInterfaceInUse(id) }) } diff --git a/submodules/TelegramUI/Sources/SharedWakeupManager.swift b/submodules/TelegramUI/Sources/SharedWakeupManager.swift index 0aef0e616f..a6a089bcd2 100644 --- a/submodules/TelegramUI/Sources/SharedWakeupManager.swift +++ b/submodules/TelegramUI/Sources/SharedWakeupManager.swift @@ -49,6 +49,7 @@ public final class SharedWakeupManager { private let beginBackgroundTask: (String, @escaping () -> Void) -> UIBackgroundTaskIdentifier? private let endBackgroundTask: (UIBackgroundTaskIdentifier) -> Void private let backgroundTimeRemaining: () -> Double + private let acquireIdleExtension: () -> Disposable? private var inForeground: Bool = false private var hasActiveAudioSession: Bool = false @@ -65,15 +66,17 @@ public final class SharedWakeupManager { private var currentExternalCompletionValidationTimer: SwiftSignalKit.Timer? private var managedPausedInBackgroundPlayer: Disposable? + private var keepIdleDisposable: Disposable? private var accountsAndTasks: [(Account, Bool, AccountTasks)] = [] - public init(beginBackgroundTask: @escaping (String, @escaping () -> Void) -> UIBackgroundTaskIdentifier?, endBackgroundTask: @escaping (UIBackgroundTaskIdentifier) -> Void, backgroundTimeRemaining: @escaping () -> Double, activeAccounts: Signal<(primary: Account?, accounts: [(AccountRecordId, Account)]), NoError>, liveLocationPolling: Signal, watchTasks: Signal, inForeground: Signal, hasActiveAudioSession: Signal, notificationManager: SharedNotificationManager?, mediaManager: MediaManager, callManager: PresentationCallManager?, accountUserInterfaceInUse: @escaping (AccountRecordId) -> Signal) { + public init(beginBackgroundTask: @escaping (String, @escaping () -> Void) -> UIBackgroundTaskIdentifier?, endBackgroundTask: @escaping (UIBackgroundTaskIdentifier) -> Void, backgroundTimeRemaining: @escaping () -> Double, acquireIdleExtension: @escaping () -> Disposable?, activeAccounts: Signal<(primary: Account?, accounts: [(AccountRecordId, Account)]), NoError>, liveLocationPolling: Signal, watchTasks: Signal, inForeground: Signal, hasActiveAudioSession: Signal, notificationManager: SharedNotificationManager?, mediaManager: MediaManager, callManager: PresentationCallManager?, accountUserInterfaceInUse: @escaping (AccountRecordId) -> Signal) { assert(Queue.mainQueue().isCurrent()) self.beginBackgroundTask = beginBackgroundTask self.endBackgroundTask = endBackgroundTask self.backgroundTimeRemaining = backgroundTimeRemaining + self.acquireIdleExtension = acquireIdleExtension self.inForegroundDisposable = (inForeground |> deliverOnMainQueue).start(next: { [weak self] value in @@ -186,6 +189,7 @@ public final class SharedWakeupManager { self.hasActiveAudioSessionDisposable?.dispose() self.tasksDisposable?.dispose() self.managedPausedInBackgroundPlayer?.dispose() + self.keepIdleDisposable?.dispose() if let (taskId, _, timer) = self.currentTask { timer.invalidate() self.endBackgroundTask(taskId) @@ -265,11 +269,15 @@ public final class SharedWakeupManager { var hasTasksForBackgroundExtension = false var hasActiveCalls = false + var hasPendingMessages = false for (_, _, tasks) in self.accountsAndTasks { if tasks.activeCalls { hasActiveCalls = true break } + if tasks.importantTasks.contains(.pendingMessages) { + hasPendingMessages = true + } } if self.inForeground || self.hasActiveAudioSession || hasActiveCalls { @@ -350,6 +358,17 @@ public final class SharedWakeupManager { } } self.updateAccounts(hasTasks: hasTasksForBackgroundExtension) + + if hasPendingMessages { + if self.keepIdleDisposable == nil { + self.keepIdleDisposable = self.acquireIdleExtension() + } + } else { + if let keepIdleDisposable = self.keepIdleDisposable { + self.keepIdleDisposable = nil + keepIdleDisposable.dispose() + } + } } private func updateAccounts(hasTasks: Bool) {