From ecaa8e54408dd7fe5ec87fc27052f406c7166362 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sun, 6 Sep 2020 07:05:39 +0100 Subject: [PATCH] IOS7: Save state as a background task when entering background This is better than using an hardcoded delay for two main reasons. The first one is that the application can terminate as soon as it has finished saving the state, and the second one is that it will still work if saving the state takes longer than the delay that was hardcoded. --- backends/platform/ios7/ios7_app_delegate.mm | 9 +++++---- backends/platform/ios7/ios7_osys_events.cpp | 8 -------- backends/platform/ios7/ios7_osys_main.cpp | 4 ++-- backends/platform/ios7/ios7_osys_misc.mm | 12 ++++++++++++ backends/platform/ios7/ios7_video.h | 5 +++++ backends/platform/ios7/ios7_video.mm | 17 +++++++++++++++++ 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/backends/platform/ios7/ios7_app_delegate.mm b/backends/platform/ios7/ios7_app_delegate.mm index 6a09f549ef5..b6ad5b03a80 100644 --- a/backends/platform/ios7/ios7_app_delegate.mm +++ b/backends/platform/ios7/ios7_app_delegate.mm @@ -87,11 +87,12 @@ } - (void)applicationDidEnterBackground:(UIApplication *)application { + // Start the background task before sending the application entered background event. + // This is because this event will be handled in a separate thread and it will likely + // no be started before we return from this function. + [[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask]; + [_view applicationEnteredBackground]; - // Add a delay so that the app continues running and gives time for the scummvm thread to - // poll the events and call saveState(). The application says we have 5 seconds to do things - // in this function before the app is terminated. Wait 2 seconds as it should be sufficient. - usleep(2000000); } - (void)applicationWillEnterForeground:(UIApplication *)application { diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp index 4e07798104a..c29f2beb871 100644 --- a/backends/platform/ios7/ios7_osys_events.cpp +++ b/backends/platform/ios7/ios7_osys_events.cpp @@ -393,14 +393,6 @@ void OSystem_iOS7::handleEvent_applicationResumed() { rebuildSurface(); } -void OSystem_iOS7::handleEvent_applicationEnteredBackground() { - saveState(); -} - -void OSystem_iOS7::handleEvent_applicationEnteredForeground() { - restoreState(); -} - void OSystem_iOS7::handleEvent_keyPressed(Common::Event &event, int keyPressed) { int ascii = keyPressed; //printf("key: %i\n", keyPressed); diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp index 1d250093465..77bd37f0572 100644 --- a/backends/platform/ios7/ios7_osys_main.cpp +++ b/backends/platform/ios7/ios7_osys_main.cpp @@ -246,9 +246,9 @@ void OSystem_iOS7::suspendLoop() { if (event.type == kInputApplicationResumed) done = true; else if (event.type == kInputApplicationEnteredBackground) - saveState(); + handleEvent_applicationEnteredBackground(); else if (event.type == kInputApplicationEnteredForeground) - restoreState(); + handleEvent_applicationEnteredForeground(); } usleep(100000); } diff --git a/backends/platform/ios7/ios7_osys_misc.mm b/backends/platform/ios7/ios7_osys_misc.mm index 1f9232c12ed..3634b583ce3 100644 --- a/backends/platform/ios7/ios7_osys_misc.mm +++ b/backends/platform/ios7/ios7_osys_misc.mm @@ -28,6 +28,8 @@ #include #include #include "common/translation.h" +#include "backends/platform/ios7/ios7_app_delegate.h" +#include "backends/platform/ios7/ios7_video.h" static inline void execute_on_main_thread_async(void (^block)(void)) { if ([NSThread currentThread] == [NSThread mainThread]) { @@ -108,3 +110,13 @@ bool OSystem_iOS7::isConnectionLimited() { CFRelease(ref); return (flags & kSCNetworkReachabilityFlagsIsWWAN); } + +void OSystem_iOS7::handleEvent_applicationEnteredBackground() { + [[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask]; + saveState(); + [[iOS7AppDelegate iPhoneView] endBackgroundSaveStateTask]; +} + +void OSystem_iOS7::handleEvent_applicationEnteredForeground() { + restoreState(); +} diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h index 733372ffe11..1ed79f1f98a 100644 --- a/backends/platform/ios7/ios7_video.h +++ b/backends/platform/ios7/ios7_video.h @@ -50,6 +50,8 @@ typedef struct { SoftKeyboard *_keyboardView; BOOL _keyboardVisible; + UIBackgroundTaskIdentifier _backgroundSaveStateTask; + EAGLContext *_context; GLuint _viewRenderbuffer; GLuint _viewFramebuffer; @@ -132,6 +134,9 @@ typedef struct { - (void)applicationEnteredBackground; - (void)applicationEnteredForeground; +- (void) beginBackgroundSaveStateTask; +- (void) endBackgroundSaveStateTask; + - (bool)fetchEvent:(InternalEvent *)event; @end diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm index 5973f125643..cdc13dc228c 100644 --- a/backends/platform/ios7/ios7_video.mm +++ b/backends/platform/ios7/ios7_video.mm @@ -421,6 +421,8 @@ uint getSizeNextPOT(uint size) { - (id)initWithFrame:(struct CGRect)frame { self = [super initWithFrame: frame]; + _backgroundSaveStateTask = UIBackgroundTaskInvalid; + #if defined(USE_SCALERS) || defined(USE_HQ_SCALERS) InitScalers(565); #endif @@ -1115,4 +1117,19 @@ uint getSizeNextPOT(uint size) { [self addEvent:InternalEvent(kInputApplicationEnteredForeground, 0, 0)]; } +- (void) beginBackgroundSaveStateTask { + if (_backgroundSaveStateTask == UIBackgroundTaskInvalid) { + _backgroundSaveStateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ + [self endBackgroundSaveStateTask]; + }]; + } +} + +- (void) endBackgroundSaveStateTask { + if (_backgroundSaveStateTask != UIBackgroundTaskInvalid) { + [[UIApplication sharedApplication] endBackgroundTask: _backgroundSaveStateTask]; + _backgroundSaveStateTask = UIBackgroundTaskInvalid; + } +} + @end