diff options
author | NicoleYarroch <nicole@livio.io> | 2020-04-09 17:02:07 -0400 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2020-04-09 17:02:07 -0400 |
commit | 6bc0d8cb7984980d568e1a6c82e0bb8c3af77bed (patch) | |
tree | 8e8e796f156a3ca0b8f3a3493db04135ed4ccf8c | |
parent | c806df40276b22f8b5938551d11a9305567610a9 (diff) | |
download | sdl_ios-6bc0d8cb7984980d568e1a6c82e0bb8c3af77bed.tar.gz |
Refactored background task ended handler
-rw-r--r-- | SmartDeviceLink/SDLBackgroundTaskManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLBackgroundTaskManager.m | 31 | ||||
-rw-r--r-- | SmartDeviceLink/SDLSecondaryTransportManager.m | 9 |
3 files changed, 31 insertions, 14 deletions
diff --git a/SmartDeviceLink/SDLBackgroundTaskManager.h b/SmartDeviceLink/SDLBackgroundTaskManager.h index 7ed45f08d..5c1c7eb57 100644 --- a/SmartDeviceLink/SDLBackgroundTaskManager.h +++ b/SmartDeviceLink/SDLBackgroundTaskManager.h @@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLBackgroundTaskManager : NSObject /// Handler called when the background task is about to expire. Use this handler to perform some cleanup before the background task is destroyed. When you have finished cleanup, you must call the `endBackgroundTask` function so the background task can be destroyed. If you do not call `endBackgroundTask`, the system may kill the app. -@property (copy, nonatomic, nullable) void (^taskEndedHandler)(void); +@property (copy, nonatomic, nullable) BOOL (^taskExpiringHandler)(void); - (instancetype)init NS_UNAVAILABLE; @@ -35,6 +35,9 @@ NS_ASSUME_NONNULL_BEGIN /// Destroys the background task. - (void)endBackgroundTask; +/// Destroys the background task after cleanup has finished. This should only be called if you have subscribed to the `taskExpiringHandler` in order to do some cleanup before the background task is destroyed. +- (void)expiredTaskCleanupFinished; + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLBackgroundTaskManager.m b/SmartDeviceLink/SDLBackgroundTaskManager.m index 4848073b4..4b6e09a64 100644 --- a/SmartDeviceLink/SDLBackgroundTaskManager.m +++ b/SmartDeviceLink/SDLBackgroundTaskManager.m @@ -41,13 +41,22 @@ NS_ASSUME_NONNULL_BEGIN __weak typeof(self) weakSelf = self; self.currentBackgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithName:self.backgroundTaskName expirationHandler:^{ - // We have ~1 second to do cleanup before ending the background task. If we take too long, the system will kill the app. __strong typeof(weakSelf) strongSelf = weakSelf; - SDLLogD(@"The background task %@ expired", strongSelf.backgroundTaskName); - if (strongSelf.taskEndedHandler != nil) { - SDLLogD(@"Waiting for cleanup to finish before ending the background task"); - strongSelf.taskEndedHandler(); + SDLLogD(@"The background task %@ is expiring.", strongSelf.backgroundTaskName); + + // We have ~1 second to do cleanup before ending the background task. If we take too long, the system will kill the app. + if (strongSelf.taskExpiringHandler != nil) { + SDLLogD(@"Checking if subscriber wants to to perform some cleanup before ending the background task %@", strongSelf.backgroundTaskName); + BOOL waitForCleanupToFinish = strongSelf.taskExpiringHandler(); + if (waitForCleanupToFinish) { + SDLLogD(@"Subscriber wants to clean up before ending the background task %@. Waiting...", self.backgroundTaskName); + } else { + SDLLogV(@"Subscriber does not want to perform cleanup. Ending the background task %@", strongSelf.backgroundTaskName); + [strongSelf endBackgroundTask]; + } } else { + // No subscriber. Just end the background task. + SDLLogV(@"Ending background task %@", strongSelf.backgroundTaskName); [strongSelf endBackgroundTask]; } }]; @@ -55,13 +64,15 @@ NS_ASSUME_NONNULL_BEGIN SDLLogD(@"The %@ background task started with id: %lu", self.backgroundTaskName, (unsigned long)self.currentBackgroundTaskId); } +- (void)expiredTaskCleanupFinished { + if (self.taskExpiringHandler == nil) { return; } + SDLLogD(@"Ending background task %@ because clean up has finished.", self.backgroundTaskName); + [self endBackgroundTask]; +} + - (void)endBackgroundTask { SDLLogV(@"Attempting to end background task %@", self.backgroundTaskName); - - if (self.taskEndedHandler != nil) { - SDLLogD(@"Background task %@ cleanup finished", self.backgroundTaskName); - self.taskEndedHandler = nil; - } + self.taskExpiringHandler = nil; if (self.currentBackgroundTaskId == UIBackgroundTaskInvalid) { SDLLogV(@"Background task %@ with id %lu already ended. Returning...", self.backgroundTaskName, (unsigned long)self.currentBackgroundTaskId); diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 9f996522d..b57d1e635 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -438,7 +438,7 @@ struct TransportProtocolUpdated { self.secondaryTransport = nil; self.secondaryProtocol = nil; - [self.backgroundTaskManager endBackgroundTask]; + [self.backgroundTaskManager expiredTaskCleanupFinished]; return YES; } @@ -685,7 +685,7 @@ struct TransportProtocolUpdated { SDLLogD(@"App will enter the background"); if ([strongSelf sdl_isTransportOpened] && strongSelf.secondaryTransportType == SDLSecondaryTransportTypeTCP) { SDLLogD(@"Starting background task to keep TCP transport alive"); - strongSelf.backgroundTaskManager.taskEndedHandler = [strongSelf sdl_backgroundTaskEndedHandler]; + strongSelf.backgroundTaskManager.taskExpiringHandler = [strongSelf sdl_backgroundTaskEndedHandler]; [strongSelf.backgroundTaskManager startBackgroundTask]; } else { SDLLogD(@"TCP transport already disconnected, will not start a background task."); @@ -711,17 +711,20 @@ struct TransportProtocolUpdated { /// Handles a notification that the background task has ended. If the app is still in the background, the TCP transport disconnects. If the app has re-entered the foreground or the manager has shutdown then the notification is ignored. /// @return A background task ended handler -- (nullable void (^)(void))sdl_backgroundTaskEndedHandler { +- (nullable BOOL (^)(void))sdl_backgroundTaskEndedHandler { __weak typeof(self) weakSelf = self; return ^{ __strong typeof(self) strongSelf = weakSelf; if (strongSelf.sdl_getAppState == UIApplicationStateActive) { SDLLogV(@"App has been foregrounded. Ignoring notification that the background task ended."); + return NO; } else if ([strongSelf.stateMachine isCurrentState:SDLSecondaryTransportStateStopped]) { SDLLogV(@"Manager has been stopped. Ignoring notification that the background task ended."); + return NO; } else { SDLLogD(@"Disconnecting TCP transport due to the background task ending."); [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; + return YES; } }; } |