WIP: background vibrate & refresh tasks

This commit is contained in:
ryanzhao 2021-10-12 16:43:30 +11:00
parent 9b9a5d7a39
commit c1e5511ed4
4 changed files with 81 additions and 5 deletions

View file

@ -224,6 +224,10 @@ static NSTimeInterval launchStartedAt;
OWSLogInfo(@"application: didFinishLaunchingWithOptions completed."); OWSLogInfo(@"application: didFinishLaunchingWithOptions completed.");
[self setUpCallHandling]; [self setUpCallHandling];
if (@available(iOS 13.0, *)) {
[self registerBackgroundTasks];
}
return YES; return YES;
} }

View file

@ -2,11 +2,13 @@ import PromiseKit
import WebRTC import WebRTC
import SessionUIKit import SessionUIKit
import UIKit import UIKit
import BackgroundTasks
import SessionUtilitiesKit
extension AppDelegate { extension AppDelegate {
@objc // MARK: Call handling
func setUpCallHandling() { @objc func setUpCallHandling() {
// Offer messages // Offer messages
MessageReceiver.handleOfferCallMessage = { message in MessageReceiver.handleOfferCallMessage = { message in
DispatchQueue.main.async { DispatchQueue.main.async {
@ -45,6 +47,7 @@ extension AppDelegate {
} }
} }
// MARK: Configuration message
@objc(syncConfigurationIfNeeded) @objc(syncConfigurationIfNeeded)
func syncConfigurationIfNeeded() { func syncConfigurationIfNeeded() {
guard Storage.shared.getUser()?.name != nil else { return } guard Storage.shared.getUser()?.name != nil else { return }
@ -75,6 +78,7 @@ extension AppDelegate {
return promise return promise
} }
// MARK: Closed group poller
@objc func startClosedGroupPoller() { @objc func startClosedGroupPoller() {
guard OWSIdentityManager.shared().identityKeyPair() != nil else { return } guard OWSIdentityManager.shared().identityKeyPair() != nil else { return }
ClosedGroupPoller.shared.start() ClosedGroupPoller.shared.start()
@ -84,6 +88,7 @@ extension AppDelegate {
ClosedGroupPoller.shared.stop() ClosedGroupPoller.shared.stop()
} }
// MARK: Theme
@objc func getAppModeOrSystemDefault() -> AppMode { @objc func getAppModeOrSystemDefault() -> AppMode {
let userDefaults = UserDefaults.standard let userDefaults = UserDefaults.standard
if userDefaults.dictionaryRepresentation().keys.contains("appMode") { if userDefaults.dictionaryRepresentation().keys.contains("appMode") {
@ -98,4 +103,46 @@ extension AppDelegate {
} }
} }
// MARK: Background tasks
@available(iOS 13.0, *)
@objc func registerBackgroundTasks() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.loki-project.loki-messenger.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.loki-project.loki-messenger.vibrate", using: nil) { task in
Vibration.shared.startVibration()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 60, execute: {
Vibration.shared.stopVibrationIfPossible()
task.setTaskCompleted(success: true)
})
}
}
@available(iOS 13.0, *)
@objc func cancelAllPendingBGTask() {
BGTaskScheduler.shared.cancelAllTaskRequests()
}
@available(iOS 13.0, *)
@objc func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.loki-project.loki-messenger.refresh")
// Fetch no earlier than 15 minutes from now.
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
@available(iOS 13.0, *)
private func handleAppRefresh(task: BGAppRefreshTask) {
// Schedule a new refresh task.
scheduleAppRefresh()
}
} }

View file

@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.loki-project.loki-messenger.vibrate</string>
<string>com.loki-project.loki-messenger.refresh</string>
</array>
<key>BuildDetails</key> <key>BuildDetails</key>
<dict> <dict>
<key>CarthageVersion</key> <key>CarthageVersion</key>
@ -90,7 +95,7 @@
<key>NSContactsUsageDescription</key> <key>NSContactsUsageDescription</key>
<string>Signal uses your contacts to find users you know. We do not store your contacts on the server.</string> <string>Signal uses your contacts to find users you know. We do not store your contacts on the server.</string>
<key>NSFaceIDUsageDescription</key> <key>NSFaceIDUsageDescription</key>
<string>Session's Screen Lock feature uses Face ID.</string> <string>Session&apos;s Screen Lock feature uses Face ID.</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>Session needs access to your microphone to record media.</string> <string>Session needs access to your microphone to record media.</string>
<key>NSPhotoLibraryAddUsageDescription</key> <key>NSPhotoLibraryAddUsageDescription</key>
@ -119,6 +124,7 @@
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>
<string>processing</string>
<string>remote-notification</string> <string>remote-notification</string>
</array> </array>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
@ -135,5 +141,7 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key>
<string>com.loki-project.loki-messenger</string>
</dict> </dict>
</plist> </plist>

View file

@ -1,4 +1,5 @@
import UserNotifications import UserNotifications
import BackgroundTasks
import SessionMessagingKit import SessionMessagingKit
import SignalUtilitiesKit import SignalUtilitiesKit
@ -93,7 +94,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
notificationContent.badge = 1 notificationContent.badge = 1
notificationContent.title = "Session" notificationContent.title = "Session"
notificationContent.body = "\(senderDisplayName) is calling..." notificationContent.body = "\(senderDisplayName) is calling..."
return self.handleSuccess(for: notificationContent) return self.handleSuccessForIncomingCall(for: notificationContent)
default: return self.completeSilenty() default: return self.completeSilenty()
} }
if (senderPublicKey == userPublicKey) { if (senderPublicKey == userPublicKey) {
@ -119,7 +120,10 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
} }
self.handleSuccess(for: notificationContent) self.handleSuccess(for: notificationContent)
} catch { } catch {
self.handleFailure(for: notificationContent) if let error = error as? MessageReceiver.Error, error.isRetryable {
self.handleFailure(for: notificationContent)
}
self.completeSilenty()
} }
} }
} }
@ -209,6 +213,19 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
private func completeSilenty() { private func completeSilenty() {
contentHandler!(.init()) contentHandler!(.init())
} }
private func handleSuccessForIncomingCall(for content: UNMutableNotificationContent) {
// TODO: poll for the real offer, play incoming call ring
if #available(iOSApplicationExtension 13.0, *) {
let request = BGAppRefreshTaskRequest(identifier: "com.loki-project.loki-messenger.refresh")
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
contentHandler!(content)
}
private func handleSuccess(for content: UNMutableNotificationContent) { private func handleSuccess(for content: UNMutableNotificationContent) {
contentHandler!(content) contentHandler!(content)