mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Don't read "PIC" tags as they might be too large
This commit is contained in:
parent
1eb0916e25
commit
47c4ab17a3
@ -1229,6 +1229,9 @@ final class SharedApplicationContext {
|
|||||||
extendNow = true
|
extendNow = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
extendNow = false
|
||||||
|
#endif
|
||||||
sharedApplicationContext.wakeupManager.allowBackgroundTimeExtension(timeout: 4.0, extendNow: extendNow)
|
sharedApplicationContext.wakeupManager.allowBackgroundTimeExtension(timeout: 4.0, extendNow: extendNow)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1300,7 +1303,20 @@ final class SharedApplicationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.shared.log("App \(self.episodeId)", "remoteNotification: \(redactedPayload)")
|
Logger.shared.log("App \(self.episodeId)", "remoteNotification: \(redactedPayload)")
|
||||||
completionHandler(UIBackgroundFetchResult.noData)
|
|
||||||
|
if userInfo["p"] == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = (self.sharedContextPromise.get()
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { sharedApplicationContext in
|
||||||
|
|
||||||
|
sharedApplicationContext.wakeupManager.replaceCurrentExtensionWithExternalTime(completion: {
|
||||||
|
completionHandler(.newData)
|
||||||
|
}, timeout: 29.0)
|
||||||
|
sharedApplicationContext.notificationManager.addNotification(userInfo)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
|
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
|
||||||
@ -1325,261 +1341,11 @@ final class SharedApplicationContext {
|
|||||||
|
|
||||||
if case PKPushType.voIP = type {
|
if case PKPushType.voIP = type {
|
||||||
Logger.shared.log("App \(self.episodeId)", "pushRegistry payload: \(payload.dictionaryPayload)")
|
Logger.shared.log("App \(self.episodeId)", "pushRegistry payload: \(payload.dictionaryPayload)")
|
||||||
sharedApplicationContext.notificationManager.addEncryptedNotification(payload.dictionaryPayload)
|
sharedApplicationContext.notificationManager.addNotification(payload.dictionaryPayload)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private func processPushPayload(_ payload: [AnyHashable: Any], account: Account) {
|
|
||||||
let decryptedPayload: Signal<[AnyHashable: Any]?, NoError>
|
|
||||||
if let _ = payload["aps"] as? [AnyHashable: Any] {
|
|
||||||
decryptedPayload = .single(payload)
|
|
||||||
} else if var encryptedPayload = payload["p"] as? String {
|
|
||||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+")
|
|
||||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/")
|
|
||||||
while encryptedPayload.count % 4 != 0 {
|
|
||||||
encryptedPayload.append("=")
|
|
||||||
}
|
|
||||||
if let data = Data(base64Encoded: encryptedPayload) {
|
|
||||||
decryptedPayload = decryptedNotificationPayload(account: account, data: data)
|
|
||||||
|> map { value -> [AnyHashable: Any]? in
|
|
||||||
if let value = value, let object = try? JSONSerialization.jsonObject(with: value, options: []) {
|
|
||||||
return object as? [AnyHashable: Any]
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
decryptedPayload = .single(nil)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
decryptedPayload = .single(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = (decryptedPayload
|
|
||||||
|> deliverOnMainQueue).start(next: { payload in
|
|
||||||
guard let payload = payload else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var redactedPayload = payload
|
|
||||||
if var aps = redactedPayload["aps"] as? [AnyHashable: Any] {
|
|
||||||
if Logger.shared.redactSensitiveData {
|
|
||||||
if aps["alert"] != nil {
|
|
||||||
aps["alert"] = "[[redacted]]"
|
|
||||||
}
|
|
||||||
if aps["body"] != nil {
|
|
||||||
aps["body"] = "[[redacted]]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
redactedPayload["aps"] = aps
|
|
||||||
}
|
|
||||||
Logger.shared.log("Apns \(self.episodeId)", "\(redactedPayload)")
|
|
||||||
|
|
||||||
let aps = payload["aps"] as? [AnyHashable: Any]
|
|
||||||
|
|
||||||
if UIApplication.shared.applicationState == .background {
|
|
||||||
var readMessageId: MessageId?
|
|
||||||
var isCall = false
|
|
||||||
var isAnnouncement = false
|
|
||||||
var isLocationPolling = false
|
|
||||||
var isMutePolling = false
|
|
||||||
var title: String = ""
|
|
||||||
var body: String?
|
|
||||||
var apnsSound: String?
|
|
||||||
var configurationUpdate: (Int32, String, Int32, Data?)?
|
|
||||||
if let aps = aps, let alert = aps["alert"] as? String {
|
|
||||||
if let range = alert.range(of: ": ") {
|
|
||||||
title = String(alert[..<range.lowerBound])
|
|
||||||
body = String(alert[range.upperBound...])
|
|
||||||
} else {
|
|
||||||
body = alert
|
|
||||||
}
|
|
||||||
} else if let aps = aps, let alert = aps["alert"] as? [AnyHashable: AnyObject] {
|
|
||||||
if let alertBody = alert["body"] as? String {
|
|
||||||
body = alertBody
|
|
||||||
if let alertTitle = alert["title"] as? String {
|
|
||||||
title = alertTitle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let locKey = alert["loc-key"] as? String {
|
|
||||||
if locKey == "PHONE_CALL_REQUEST" {
|
|
||||||
isCall = true
|
|
||||||
} else if locKey == "GEO_LIVE_PENDING" {
|
|
||||||
isLocationPolling = true
|
|
||||||
} else if locKey == "MESSAGE_MUTED" {
|
|
||||||
isMutePolling = true
|
|
||||||
}
|
|
||||||
let string = NSLocalizedString(locKey, comment: "")
|
|
||||||
if !string.isEmpty {
|
|
||||||
if let locArgs = alert["loc-args"] as? [AnyObject] {
|
|
||||||
var args: [CVarArg] = []
|
|
||||||
var failed = false
|
|
||||||
for arg in locArgs {
|
|
||||||
if let arg = arg as? CVarArg {
|
|
||||||
args.append(arg)
|
|
||||||
} else {
|
|
||||||
failed = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if failed {
|
|
||||||
body = "\(string)"
|
|
||||||
} else {
|
|
||||||
body = String(format: string, arguments: args)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
body = "\(string)"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
body = nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
body = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let aps = aps, let address = aps["addr"] as? String, let datacenterId = aps["dc"] as? Int {
|
|
||||||
var host = address
|
|
||||||
var port: Int32 = 443
|
|
||||||
if let range = address.range(of: ":") {
|
|
||||||
host = String(address[address.startIndex ..< range.lowerBound])
|
|
||||||
if let portValue = Int(String(address[range.upperBound...])) {
|
|
||||||
port = Int32(portValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var secret: Data?
|
|
||||||
if let secretString = aps["sec"] as? String {
|
|
||||||
let data = dataWithHexString(secretString)
|
|
||||||
if data.count == 16 || data.count == 32 {
|
|
||||||
secret = data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
configurationUpdate = (Int32(datacenterId), host, port, secret)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let aps = aps, let sound = aps["sound"] as? String {
|
|
||||||
apnsSound = sound
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload["call_id"] != nil {
|
|
||||||
isCall = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload["announcement"] != nil {
|
|
||||||
isAnnouncement = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if let body = body {
|
|
||||||
if isAnnouncement {
|
|
||||||
self.queuedAnnouncements.append(body)
|
|
||||||
self.maybeDequeueAnnouncements()
|
|
||||||
} else {
|
|
||||||
var peerId: PeerId?
|
|
||||||
var notificationRequestId: NotificationManagedNotificationRequestId?
|
|
||||||
|
|
||||||
if let fromId = payload["from_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
|
||||||
} else if let fromId = payload["chat_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: Int32(fromIdValue.intValue))
|
|
||||||
} else if let fromId = payload["channel_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: Int32(fromIdValue.intValue))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let msgId = payload["msg_id"] {
|
|
||||||
let msgIdValue = msgId as! NSString
|
|
||||||
if let peerId = peerId {
|
|
||||||
notificationRequestId = .messageId(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(msgIdValue.intValue)))
|
|
||||||
}
|
|
||||||
} else if let randomId = payload["random_id"] {
|
|
||||||
let randomIdValue = randomId as! NSString
|
|
||||||
var peerId: PeerId?
|
|
||||||
if let encryptionIdString = payload["encryption_id"] as? String, let encryptionId = Int32(encryptionIdString) {
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.SecretChat, id: encryptionId)
|
|
||||||
}
|
|
||||||
notificationRequestId = .globallyUniqueId(randomIdValue.longLongValue, peerId)
|
|
||||||
} else {
|
|
||||||
isMutePolling = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if let notificationRequestId = notificationRequestId {
|
|
||||||
self.queuedNotificationRequests.append((title, body, apnsSound, notificationRequestId))
|
|
||||||
self.maybeDequeueNotificationRequests()
|
|
||||||
} else if isMutePolling {
|
|
||||||
self.queuedMutePolling = true
|
|
||||||
self.maybeDequeueNotificationRequests()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if let _ = payload["max_id"] {
|
|
||||||
var peerId: PeerId?
|
|
||||||
|
|
||||||
if let fromId = payload["from_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
|
||||||
} else if let fromId = payload["chat_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: Int32(fromIdValue.intValue))
|
|
||||||
} else if let fromId = payload["channel_id"] {
|
|
||||||
let fromIdValue = fromId as! NSString
|
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: Int32(fromIdValue.intValue))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let peerId = peerId {
|
|
||||||
if let msgId = payload["max_id"] {
|
|
||||||
let msgIdValue = msgId as! NSString
|
|
||||||
if msgIdValue.intValue != 0 {
|
|
||||||
readMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(msgIdValue.intValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var addedWakeups = Set<QueuedWakeup>()
|
|
||||||
if isCall {
|
|
||||||
addedWakeups.insert(.call)
|
|
||||||
}
|
|
||||||
if isLocationPolling {
|
|
||||||
addedWakeups.insert(.backgroundLocation)
|
|
||||||
}
|
|
||||||
if !addedWakeups.isEmpty {
|
|
||||||
self.queuedWakeups.formUnion(addedWakeups)
|
|
||||||
self.maybeDequeueWakeups()
|
|
||||||
}
|
|
||||||
if let readMessageId = readMessageId {
|
|
||||||
self.clearNotificationsManager?.append(readMessageId)
|
|
||||||
self.clearNotificationsManager?.commitNow()
|
|
||||||
|
|
||||||
let signal = self.context.get()
|
|
||||||
|> take(1)
|
|
||||||
|> mapToSignal { context -> Signal<Void, NoError> in
|
|
||||||
if let context = context {
|
|
||||||
return context.context.account.postbox.transaction (ignoreDisabled: true, { transaction -> Void in
|
|
||||||
transaction.applyIncomingReadMaxId(readMessageId)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _ = signal.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let (datacenterId, host, port, secret) = configurationUpdate {
|
|
||||||
let signal = self.context.get()
|
|
||||||
|> take(1)
|
|
||||||
|> mapToSignal { context -> Signal<Void, NoError> in
|
|
||||||
if let context = context {
|
|
||||||
context.context.account.network.mergeBackupDatacenterAddress(datacenterId: datacenterId, host: host, port: port, secret: secret)
|
|
||||||
}
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
let _ = signal.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
|
public func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
|
||||||
Logger.shared.log("App \(self.episodeId)", "invalidated token for \(type)")
|
Logger.shared.log("App \(self.episodeId)", "invalidated token for \(type)")
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,14 @@ private final class PollStateContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class NotificationInfo {
|
||||||
|
let dict: [AnyHashable: Any]
|
||||||
|
|
||||||
|
init(dict: [AnyHashable: Any]) {
|
||||||
|
self.dict = dict
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final class SharedNotificationManager {
|
public final class SharedNotificationManager {
|
||||||
private let episodeId: UInt32
|
private let episodeId: UInt32
|
||||||
private let application: UIApplication
|
private let application: UIApplication
|
||||||
@ -35,7 +43,7 @@ public final class SharedNotificationManager {
|
|||||||
private var accountsAndKeys: [(Account, Bool, MasterNotificationKey)]?
|
private var accountsAndKeys: [(Account, Bool, MasterNotificationKey)]?
|
||||||
private var accountsAndKeysDisposable: Disposable?
|
private var accountsAndKeysDisposable: Disposable?
|
||||||
|
|
||||||
private var encryptedNotifications: [[AnyHashable: Any]] = []
|
private var notifications: [NotificationInfo] = []
|
||||||
|
|
||||||
private var pollStateContexts: [AccountRecordId: PollStateContext] = [:]
|
private var pollStateContexts: [AccountRecordId: PollStateContext] = [:]
|
||||||
|
|
||||||
@ -149,8 +157,8 @@ public final class SharedNotificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addEncryptedNotification(_ dict: [AnyHashable: Any]) {
|
func addNotification(_ dict: [AnyHashable: Any]) {
|
||||||
self.encryptedNotifications.append(dict)
|
self.notifications.append(NotificationInfo(dict: dict))
|
||||||
|
|
||||||
if self.accountsAndKeys != nil {
|
if self.accountsAndKeys != nil {
|
||||||
self.process()
|
self.process()
|
||||||
@ -162,8 +170,8 @@ public final class SharedNotificationManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var decryptedNotifications: [(Account, Bool, [AnyHashable: Any])] = []
|
var decryptedNotifications: [(Account, Bool, [AnyHashable: Any])] = []
|
||||||
for dict in self.encryptedNotifications {
|
for notification in self.notifications {
|
||||||
if var encryptedPayload = dict["p"] as? String {
|
if var encryptedPayload = notification.dict["p"] as? String {
|
||||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+")
|
encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+")
|
||||||
encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/")
|
encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/")
|
||||||
while encryptedPayload.count % 4 != 0 {
|
while encryptedPayload.count % 4 != 0 {
|
||||||
@ -181,7 +189,7 @@ public final class SharedNotificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.encryptedNotifications.removeAll()
|
self.notifications.removeAll()
|
||||||
|
|
||||||
for (account, isCurrent, payload) in decryptedNotifications {
|
for (account, isCurrent, payload) in decryptedNotifications {
|
||||||
var redactedPayload = payload
|
var redactedPayload = payload
|
||||||
@ -206,7 +214,7 @@ public final class SharedNotificationManager {
|
|||||||
var isAnnouncement = false
|
var isAnnouncement = false
|
||||||
var isLocationPolling = false
|
var isLocationPolling = false
|
||||||
var notificationRequestId: NotificationManagedNotificationRequestId?
|
var notificationRequestId: NotificationManagedNotificationRequestId?
|
||||||
var isMutePolling = false
|
var shouldPollState = false
|
||||||
var title: String = ""
|
var title: String = ""
|
||||||
var body: String?
|
var body: String?
|
||||||
var apnsSound: String?
|
var apnsSound: String?
|
||||||
@ -234,7 +242,7 @@ public final class SharedNotificationManager {
|
|||||||
} else if locKey == "GEO_LIVE_PENDING" {
|
} else if locKey == "GEO_LIVE_PENDING" {
|
||||||
isLocationPolling = true
|
isLocationPolling = true
|
||||||
} else if locKey == "MESSAGE_MUTED" {
|
} else if locKey == "MESSAGE_MUTED" {
|
||||||
isMutePolling = true
|
shouldPollState = true
|
||||||
} else if locKey == "MESSAGE_DELETED" {
|
} else if locKey == "MESSAGE_DELETED" {
|
||||||
var peerId: PeerId?
|
var peerId: PeerId?
|
||||||
if let fromId = payload["from_id"] {
|
if let fromId = payload["from_id"] {
|
||||||
@ -281,8 +289,6 @@ public final class SharedNotificationManager {
|
|||||||
} else {
|
} else {
|
||||||
body = nil
|
body = nil
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
body = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +332,8 @@ public final class SharedNotificationManager {
|
|||||||
} else {
|
} else {
|
||||||
var peerId: PeerId?
|
var peerId: PeerId?
|
||||||
|
|
||||||
|
shouldPollState = true
|
||||||
|
|
||||||
if let fromId = payload["from_id"] {
|
if let fromId = payload["from_id"] {
|
||||||
let fromIdValue = fromId as! NSString
|
let fromIdValue = fromId as! NSString
|
||||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: Int32(fromIdValue.intValue))
|
||||||
@ -350,7 +358,7 @@ public final class SharedNotificationManager {
|
|||||||
}
|
}
|
||||||
notificationRequestId = .globallyUniqueId(randomIdValue.longLongValue, peerId)
|
notificationRequestId = .globallyUniqueId(randomIdValue.longLongValue, peerId)
|
||||||
} else {
|
} else {
|
||||||
isMutePolling = true
|
shouldPollState = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let _ = payload["max_id"] {
|
} else if let _ = payload["max_id"] {
|
||||||
@ -386,7 +394,7 @@ public final class SharedNotificationManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if notificationRequestId != nil || isMutePolling || isCall {
|
if notificationRequestId != nil || shouldPollState || isCall {
|
||||||
if !self.inForeground || !isCurrent {
|
if !self.inForeground || !isCurrent {
|
||||||
self.beginPollingState(account: account)
|
self.beginPollingState(account: account)
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,8 @@ public final class SharedWakeupManager {
|
|||||||
private var hasActiveAudioSessionDisposable: Disposable?
|
private var hasActiveAudioSessionDisposable: Disposable?
|
||||||
private var tasksDisposable: Disposable?
|
private var tasksDisposable: Disposable?
|
||||||
private var currentTask: (UIBackgroundTaskIdentifier, Double, SwiftSignalKit.Timer)?
|
private var currentTask: (UIBackgroundTaskIdentifier, Double, SwiftSignalKit.Timer)?
|
||||||
|
private var currentExternalCompletion: (() -> Void, SwiftSignalKit.Timer)?
|
||||||
|
private var currentExternalCompletionValidationTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private var managedPausedInBackgroundPlayer: Disposable?
|
private var managedPausedInBackgroundPlayer: Disposable?
|
||||||
|
|
||||||
@ -201,8 +203,51 @@ public final class SharedWakeupManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func replaceCurrentExtensionWithExternalTime(completion: @escaping () -> Void, timeout: Double) {
|
||||||
|
if let (currentCompletion, timer) = self.currentExternalCompletion {
|
||||||
|
currentCompletion()
|
||||||
|
timer.invalidate()
|
||||||
|
self.currentExternalCompletion = nil
|
||||||
|
}
|
||||||
|
let timer = SwiftSignalKit.Timer(timeout: timeout - 5.0, repeat: false, completion: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.currentExternalCompletionValidationTimer?.invalidate()
|
||||||
|
strongSelf.currentExternalCompletionValidationTimer = nil
|
||||||
|
if let (completion, timer) = strongSelf.currentExternalCompletion {
|
||||||
|
strongSelf.currentExternalCompletion = nil
|
||||||
|
timer.invalidate()
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
strongSelf.checkTasks()
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.currentExternalCompletion = (completion, timer)
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
self.currentExternalCompletionValidationTimer?.invalidate()
|
||||||
|
let validationTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: false, completion: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.currentExternalCompletionValidationTimer?.invalidate()
|
||||||
|
strongSelf.currentExternalCompletionValidationTimer = nil
|
||||||
|
strongSelf.checkTasks()
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.currentExternalCompletionValidationTimer = validationTimer
|
||||||
|
validationTimer.start()
|
||||||
|
self.checkTasks()
|
||||||
|
}
|
||||||
|
|
||||||
func checkTasks() {
|
func checkTasks() {
|
||||||
|
var hasTasksForBackgroundExtension = false
|
||||||
if self.inForeground || self.hasActiveAudioSession {
|
if self.inForeground || self.hasActiveAudioSession {
|
||||||
|
if let (completion, timer) = self.currentExternalCompletion {
|
||||||
|
self.currentExternalCompletion = nil
|
||||||
|
completion()
|
||||||
|
timer.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
if let (taskId, _, timer) = self.currentTask {
|
if let (taskId, _, timer) = self.currentTask {
|
||||||
self.currentTask = nil
|
self.currentTask = nil
|
||||||
timer.invalidate()
|
timer.invalidate()
|
||||||
@ -210,13 +255,21 @@ public final class SharedWakeupManager {
|
|||||||
self.isInBackgroundExtension = false
|
self.isInBackgroundExtension = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var hasTasksForBackgroundExtension = false
|
|
||||||
for (_, _, tasks) in self.accountsAndTasks {
|
for (_, _, tasks) in self.accountsAndTasks {
|
||||||
if !tasks.isEmpty {
|
if !tasks.isEmpty {
|
||||||
hasTasksForBackgroundExtension = true
|
hasTasksForBackgroundExtension = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !hasTasksForBackgroundExtension && self.currentExternalCompletionValidationTimer == nil {
|
||||||
|
if let (completion, timer) = self.currentExternalCompletion {
|
||||||
|
self.currentExternalCompletion = nil
|
||||||
|
completion()
|
||||||
|
timer.invalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.activeExplicitExtensionTimer != nil {
|
if self.activeExplicitExtensionTimer != nil {
|
||||||
hasTasksForBackgroundExtension = true
|
hasTasksForBackgroundExtension = true
|
||||||
}
|
}
|
||||||
@ -265,11 +318,11 @@ public final class SharedWakeupManager {
|
|||||||
self.isInBackgroundExtension = false
|
self.isInBackgroundExtension = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.updateAccounts()
|
self.updateAccounts(hasTasks: hasTasksForBackgroundExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateAccounts() {
|
private func updateAccounts(hasTasks: Bool) {
|
||||||
if self.inForeground || self.hasActiveAudioSession || self.isInBackgroundExtension || self.activeExplicitExtensionTimer != nil {
|
if self.inForeground || self.hasActiveAudioSession || self.isInBackgroundExtension || (hasTasks && self.currentExternalCompletion != nil) || self.activeExplicitExtensionTimer != nil {
|
||||||
for (account, primary, tasks) in self.accountsAndTasks {
|
for (account, primary, tasks) in self.accountsAndTasks {
|
||||||
if (self.inForeground && primary) || !tasks.isEmpty || (self.activeExplicitExtensionTimer != nil && primary) {
|
if (self.inForeground && primary) || !tasks.isEmpty || (self.activeExplicitExtensionTimer != nil && primary) {
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.always))
|
account.shouldBeServiceTaskMaster.set(.single(.always))
|
||||||
|
@ -791,7 +791,7 @@ typedef struct ID3v2EMFunc {
|
|||||||
|
|
||||||
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
|
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
|
||||||
{ "GEO", "GEOB", read_geobtag, free_geobtag },
|
{ "GEO", "GEOB", read_geobtag, free_geobtag },
|
||||||
{ "PIC", "APIC", read_apic, free_apic },
|
//{ "PIC", "APIC", read_apic, free_apic },
|
||||||
{ "CHAP","CHAP", read_chapter, free_chapter },
|
{ "CHAP","CHAP", read_chapter, free_chapter },
|
||||||
{ "PRIV","PRIV", read_priv, free_priv },
|
{ "PRIV","PRIV", read_priv, free_priv },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user