2017-04-27 21:11:30 +02:00
|
|
|
//
|
2018-03-21 18:25:39 +01:00
|
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
2017-04-27 21:11:30 +02:00
|
|
|
//
|
2016-10-10 22:02:09 +02:00
|
|
|
|
|
|
|
import PromiseKit
|
2017-11-28 00:17:46 +01:00
|
|
|
import SignalServiceKit
|
2016-10-10 22:02:09 +02:00
|
|
|
|
|
|
|
@objc(OWSSyncPushTokensJob)
|
2017-04-27 21:11:30 +02:00
|
|
|
class SyncPushTokensJob: NSObject {
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
|
2017-11-18 00:04:20 +01:00
|
|
|
@objc public static let PushTokensDidChange = Notification.Name("PushTokensDidChange")
|
|
|
|
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
// MARK: Dependencies
|
2016-10-10 22:02:09 +02:00
|
|
|
let accountManager: AccountManager
|
2017-09-14 21:45:04 +02:00
|
|
|
let preferences: OWSPreferences
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
var pushRegistrationManager: PushRegistrationManager {
|
|
|
|
return PushRegistrationManager.shared
|
|
|
|
}
|
|
|
|
|
2018-05-25 23:17:15 +02:00
|
|
|
@objc var uploadOnlyIfStale = true
|
2016-10-10 22:02:09 +02:00
|
|
|
|
2018-05-25 23:17:15 +02:00
|
|
|
@objc
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
required init(accountManager: AccountManager, preferences: OWSPreferences) {
|
2016-10-10 22:02:09 +02:00
|
|
|
self.accountManager = accountManager
|
|
|
|
self.preferences = preferences
|
|
|
|
}
|
|
|
|
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
class func run(accountManager: AccountManager, preferences: OWSPreferences) -> Promise<Void> {
|
|
|
|
let job = self.init(accountManager: accountManager, preferences: preferences)
|
2017-08-11 22:29:05 +02:00
|
|
|
return job.run()
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
|
2017-08-11 22:29:05 +02:00
|
|
|
func run() -> Promise<Void> {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("Starting.")
|
2016-10-10 22:02:09 +02:00
|
|
|
|
2017-09-05 23:13:49 +02:00
|
|
|
let runPromise: Promise<Void> = DispatchQueue.main.promise {
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
// HACK: no-op dispatch to work around a bug in PromiseKit/Swift which won't compile
|
|
|
|
// when dispatching complex Promise types. We should eventually be able to delete the
|
|
|
|
// following two lines, skipping this no-op dispatch.
|
|
|
|
return
|
2017-09-06 19:28:47 +02:00
|
|
|
}.then {
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
return self.pushRegistrationManager.requestPushTokens()
|
2017-09-05 23:13:49 +02:00
|
|
|
}.then { (pushToken: String, voipToken: String) in
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("finished: requesting push tokens")
|
2017-05-10 23:02:02 +02:00
|
|
|
var shouldUploadTokens = false
|
|
|
|
|
2017-04-27 21:11:00 +02:00
|
|
|
if self.preferences.getPushToken() != pushToken || self.preferences.getVoipToken() != voipToken {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.debug("Push tokens changed.")
|
2017-05-10 23:02:02 +02:00
|
|
|
shouldUploadTokens = true
|
|
|
|
} else if !self.uploadOnlyIfStale {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.debug("Forced uploading, even though tokens didn't change.")
|
2017-05-10 23:02:02 +02:00
|
|
|
shouldUploadTokens = true
|
2017-04-27 21:11:00 +02:00
|
|
|
}
|
|
|
|
|
2018-08-02 21:18:40 +02:00
|
|
|
if AppVersion.sharedInstance().lastAppVersion != AppVersion.sharedInstance().currentAppVersion {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("Uploading due to fresh install or app upgrade.")
|
2017-05-09 21:58:40 +02:00
|
|
|
shouldUploadTokens = true
|
|
|
|
}
|
|
|
|
|
2017-04-27 21:11:00 +02:00
|
|
|
guard shouldUploadTokens else {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("No reason to upload pushToken: \(pushToken), voipToken: \(voipToken)")
|
2017-04-27 21:11:00 +02:00
|
|
|
return Promise(value: ())
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.warn("uploading tokens to account servers. pushToken: \(pushToken), voipToken: \(voipToken)")
|
2018-03-21 18:25:39 +01:00
|
|
|
return self.accountManager.updatePushTokens(pushToken: pushToken, voipToken: voipToken).then {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("successfully updated push tokens on server")
|
2018-03-21 18:25:39 +01:00
|
|
|
return self.recordPushTokensLocally(pushToken: pushToken, voipToken: voipToken)
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
}.then {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("completed successfully.")
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
}.catch { error in
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.error("Failed with error: \(error).")
|
2017-05-10 23:04:43 +02:00
|
|
|
}
|
2017-05-04 19:49:44 +02:00
|
|
|
|
2017-05-09 16:11:19 +02:00
|
|
|
runPromise.retainUntilComplete()
|
2017-08-11 22:29:05 +02:00
|
|
|
|
|
|
|
return runPromise
|
|
|
|
}
|
|
|
|
|
2018-08-02 21:18:40 +02:00
|
|
|
// MARK: - objc wrappers, since objc can't use swift parameterized types
|
2017-08-11 22:29:05 +02:00
|
|
|
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
@objc class func run(accountManager: AccountManager, preferences: OWSPreferences) -> AnyPromise {
|
|
|
|
let promise: Promise<Void> = self.run(accountManager: accountManager, preferences: preferences)
|
2017-08-11 22:29:05 +02:00
|
|
|
return AnyPromise(promise)
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc func run() -> AnyPromise {
|
|
|
|
let promise: Promise<Void> = self.run()
|
|
|
|
return AnyPromise(promise)
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
|
Rework push registration
== Account Registration ==
Not complete until push tokens are uploaded
== Remote Notifications Registration ==
Extracted from PushManager
- wait for notification-settings registration to complete before
requesting push tokens, otherwise it's possible token requests will
be ignored.
- Less state required for push notification callbacks, specifically, we
no longer need to ensure we've created a promise before the
registration delegate methods get called.
- no more TOCFuture in Signal-iOS (still in SSK for now). It's not in
cases of inexplicable behavior - one a recently, push notification
premature free, in redphone, and more popular use, and I've seen two
futures inexplicably being nil. Instead, let's consolidate around
PromiseKit for popularly used, maintained, strongly-typed futures.
- separate logic for registering for vanilla push/voip notifications
(few dependencies) from responding to UILocalNotifications (lots of
dependencies). Ultimately I'd like to consolidate the remaining
UILocalNotifications logic with the existing NotificationsManager
== Misc ==
more debug logging
more uniform logging
remove stale logic around newly registered user
// FREEBIE
2017-09-20 23:47:12 +02:00
|
|
|
private func recordPushTokensLocally(pushToken: String, voipToken: String) -> Promise<Void> {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.warn("Recording push tokens locally. pushToken: \(pushToken), voipToken: \(voipToken)")
|
2016-10-10 22:02:09 +02:00
|
|
|
|
2017-11-18 00:04:20 +01:00
|
|
|
var didTokensChange = false
|
|
|
|
|
2016-10-10 22:02:09 +02:00
|
|
|
if (pushToken != self.preferences.getPushToken()) {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("Recording new plain push token")
|
2017-04-27 21:11:30 +02:00
|
|
|
self.preferences.setPushToken(pushToken)
|
2017-11-18 00:04:20 +01:00
|
|
|
didTokensChange = true
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (voipToken != self.preferences.getVoipToken()) {
|
2018-08-23 16:37:34 +02:00
|
|
|
Logger.info("Recording new voip token")
|
2017-04-27 21:11:30 +02:00
|
|
|
self.preferences.setVoipToken(voipToken)
|
2017-11-18 00:04:20 +01:00
|
|
|
didTokensChange = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if (didTokensChange) {
|
2018-03-21 18:25:39 +01:00
|
|
|
NotificationCenter.default.postNotificationNameAsync(SyncPushTokensJob.PushTokensDidChange, object: nil)
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
|
2017-04-27 21:11:30 +02:00
|
|
|
return Promise(value: ())
|
2016-10-10 22:02:09 +02:00
|
|
|
}
|
|
|
|
}
|