summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicoleYarroch <nicole@livio.io>2020-04-09 17:02:07 -0400
committerNicoleYarroch <nicole@livio.io>2020-04-09 17:02:07 -0400
commit6bc0d8cb7984980d568e1a6c82e0bb8c3af77bed (patch)
tree8e8e796f156a3ca0b8f3a3493db04135ed4ccf8c
parentc806df40276b22f8b5938551d11a9305567610a9 (diff)
downloadsdl_ios-6bc0d8cb7984980d568e1a6c82e0bb8c3af77bed.tar.gz
Refactored background task ended handler
-rw-r--r--SmartDeviceLink/SDLBackgroundTaskManager.h5
-rw-r--r--SmartDeviceLink/SDLBackgroundTaskManager.m31
-rw-r--r--SmartDeviceLink/SDLSecondaryTransportManager.m9
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;
}
};
}