Merge branch 'charlesmchen/reportedApplicationState'

pull/1/head
Matthew Chen 7 years ago
commit eabcfbfa22

@ -233,7 +233,6 @@ typedef enum : NSUInteger {
@property (nonatomic) BOOL isViewCompletelyAppeared;
@property (nonatomic) BOOL isViewVisible;
@property (nonatomic) BOOL isAppInBackground;
@property (nonatomic) BOOL shouldObserveDBModifications;
@property (nonatomic) BOOL viewHasEverAppeared;
@property (nonatomic) BOOL hasUnreadMessages;
@ -594,12 +593,12 @@ typedef enum : NSUInteger {
- (void)applicationWillEnterForeground:(NSNotification *)notification
{
[self startReadTimer];
self.isAppInBackground = NO;
[self updateCellsVisible];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
self.isAppInBackground = YES;
[self updateCellsVisible];
if (self.hasClearedUnreadMessagesIndicator) {
self.hasClearedUnreadMessagesIndicator = NO;
[self.dynamicInteractions clearUnreadIndicatorState];
@ -609,6 +608,7 @@ typedef enum : NSUInteger {
- (void)applicationWillResignActive:(NSNotification *)notification
{
[self updateShouldObserveDBModifications];
[self cancelVoiceMemo];
self.isUserScrolling = NO;
[self saveDraft];
@ -620,6 +620,7 @@ typedef enum : NSUInteger {
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
[self updateShouldObserveDBModifications];
[self startReadTimer];
}
@ -1530,7 +1531,8 @@ typedef enum : NSUInteger {
- (void)autoLoadMoreIfNecessary
{
if (self.isUserScrolling || !self.isViewVisible || self.isAppInBackground) {
BOOL isMainAppAndActive = CurrentAppContext().isMainAppAndActive;
if (self.isUserScrolling || !self.isViewVisible || !isMainAppAndActive) {
return;
}
if (!self.showLoadMoreHeader) {
@ -4428,17 +4430,10 @@ typedef enum : NSUInteger {
[self updateCellsVisible];
}
- (void)setIsAppInBackground:(BOOL)isAppInBackground
{
_isAppInBackground = isAppInBackground;
[self updateShouldObserveDBModifications];
[self updateCellsVisible];
}
- (void)updateCellsVisible
{
BOOL isCellVisible = self.isViewVisible && !self.isAppInBackground;
BOOL isAppInBackground = CurrentAppContext().isInBackground;
BOOL isCellVisible = self.isViewVisible && !isAppInBackground;
for (ConversationViewCell *cell in self.collectionView.visibleCells) {
cell.isCellVisible = isCellVisible;
}
@ -4446,7 +4441,8 @@ typedef enum : NSUInteger {
- (void)updateShouldObserveDBModifications
{
self.shouldObserveDBModifications = self.isViewVisible && !self.isAppInBackground;
BOOL isAppForegroundAndActive = CurrentAppContext().isAppForegroundAndActive;
self.shouldObserveDBModifications = self.isViewVisible && isAppForegroundAndActive;
}
- (void)setShouldObserveDBModifications:(BOOL)shouldObserveDBModifications

@ -51,7 +51,6 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
@property (nonatomic) NSSet<NSString *> *blockedPhoneNumberSet;
@property (nonatomic, readonly) NSCache<NSString *, ThreadViewModel *> *threadViewModelCache;
@property (nonatomic) BOOL isViewVisible;
@property (nonatomic) BOOL isAppInBackground;
@property (nonatomic) BOOL shouldObserveDBModifications;
@property (nonatomic) BOOL hasBeenPresented;
@ -131,14 +130,14 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
selector:@selector(applicationWillEnterForeground:)
name:OWSApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:OWSApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:OWSApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillResignActive:)
name:OWSApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yapDatabaseModified:)
name:YapDatabaseModifiedNotification
@ -484,16 +483,10 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
[self updateShouldObserveDBModifications];
}
- (void)setIsAppInBackground:(BOOL)isAppInBackground
{
_isAppInBackground = isAppInBackground;
[self updateShouldObserveDBModifications];
}
- (void)updateShouldObserveDBModifications
{
self.shouldObserveDBModifications = self.isViewVisible && !self.isAppInBackground;
BOOL isAppForegroundAndActive = CurrentAppContext().isAppForegroundAndActive;
self.shouldObserveDBModifications = self.isViewVisible && isAppForegroundAndActive;
}
- (void)setShouldObserveDBModifications:(BOOL)shouldObserveDBModifications
@ -550,15 +543,9 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
- (void)applicationWillEnterForeground:(NSNotification *)notification
{
self.isAppInBackground = NO;
[self checkIfEmptyView];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
self.isAppInBackground = YES;
}
- (BOOL)hasAnyMessagesWithTransaction:(YapDatabaseReadTransaction *)transaction
{
return [TSThread numberOfKeysInCollectionWithTransaction:transaction] > 0;
@ -566,6 +553,8 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
[self updateShouldObserveDBModifications];
// It's possible a thread was created while we where in the background. But since we don't honor contact
// requests unless the app is in the foregrond, we must check again here upon becoming active.
__block BOOL hasAnyMessages;
@ -582,6 +571,11 @@ NSString *const kArchivedConversationsReuseIdentifier = @"kArchivedConversations
}
}
- (void)applicationWillResignActive:(NSNotification *)notification
{
[self updateShouldObserveDBModifications];
}
#pragma mark - startup
- (NSArray<ExperienceUpgrade *> *)unseenUpgradeExperiences

@ -11,6 +11,14 @@
NS_ASSUME_NONNULL_BEGIN
@interface MainAppContext ()
@property (atomic) UIApplicationState reportedApplicationState;
@end
#pragma mark -
@implementation MainAppContext
@synthesize mainWindow = _mainWindow;
@ -23,6 +31,8 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
self.reportedApplicationState = UIApplicationStateInactive;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
@ -58,6 +68,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateInactive;
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationWillEnterForegroundNotification object:nil];
@ -67,6 +79,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateBackground;
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[DDLog flushLog];
@ -77,6 +91,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateInactive;
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[DDLog flushLog];
@ -87,6 +103,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateActive;
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidBecomeActiveNotification object:nil];
@ -135,12 +153,12 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)isInBackground
{
return [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;
return self.reportedApplicationState == UIApplicationStateBackground;
}
- (UIApplicationState)mainApplicationState
- (BOOL)isAppForegroundAndActive
{
return [UIApplication sharedApplication].applicationState;
return self.reportedApplicationState == UIApplicationStateActive;
}
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:

@ -56,25 +56,30 @@ NS_ASSUME_NONNULL_BEGIN
[self.uiDatabaseConnection beginLongLivedReadTransaction];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:OWSApplicationWillEnterForegroundNotification
selector:@selector(applicationDidBecomeActive:)
name:OWSApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:OWSApplicationDidEnterBackgroundNotification
selector:@selector(applicationWillResignActive:)
name:OWSApplicationWillResignActiveNotification
object:nil];
self.shouldObserveDBModifications = !CurrentAppContext().isInBackground;
[self updateShouldObserveDBModifications];
}
- (void)applicationWillEnterForeground:(NSNotification *)notification
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
self.shouldObserveDBModifications = YES;
[self updateShouldObserveDBModifications];
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
- (void)applicationWillResignActive:(NSNotification *)notification
{
self.shouldObserveDBModifications = NO;
[self updateShouldObserveDBModifications];
}
- (void)updateShouldObserveDBModifications
{
self.shouldObserveDBModifications = CurrentAppContext().isAppForegroundAndActive;
}
// Don't observe database change notifications when the app is in the background.

@ -720,9 +720,9 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
stringWithFormat:@"CipherKeySpec inaccessible. New install or no unlock since device restart? Error: %@",
error];
if (CurrentAppContext().isMainApp) {
UIApplicationState applicationState = CurrentAppContext().mainApplicationState;
errorDescription =
[errorDescription stringByAppendingFormat:@", ApplicationState: %d", (int)applicationState];
UIApplicationState applicationState = CurrentAppContext().reportedApplicationState;
errorDescription = [errorDescription
stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)];
}
DDLogError(@"%@ %@", self.logTag, errorDescription);
[DDLog flushLog];

@ -33,15 +33,33 @@ NSString *NSStringForUIApplicationState(UIApplicationState value);
@property (atomic, nullable) UIWindow *mainWindow;
// Should only be called if isMainApp is YES.
// Unlike UIApplication.applicationState, this is thread-safe.
// It contains the "last known" application state.
//
// Because it is updated in response to "will/did-style" events, it is
// conservative and skews toward less-active and not-foreground:
//
// * It doesn't report "is active" until the app is active
// and reports "inactive" as soon as it _will become_ inactive.
// * It doesn't report "is foreground (but inactive)" until the app is
// foreground & inactive and reports "background" as soon as it _will
// enter_ background.
//
// Wherever possible, use isMainAppAndActive or isInBackground instead.
// This should only be used by debugging/logging code.
- (UIApplicationState)mainApplicationState;
// This conservatism is useful, since we want to err on the side of
// caution when, for example, we do work that should only be done
// when the app is foreground and active.
@property (atomic, readonly) UIApplicationState reportedApplicationState;
// Similar to UIApplicationStateBackground, but works in SAE.
// A convenience accessor for reportedApplicationState.
//
// This method is thread-safe.
- (BOOL)isInBackground;
// A convenience accessor for reportedApplicationState.
//
// This method is thread-safe.
- (BOOL)isAppForegroundAndActive;
// Should start a background task if isMainApp is YES.
// Should just return UIBackgroundTaskInvalid if isMainApp is NO.
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:

@ -11,7 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface ShareAppExtensionContext ()
@property (nonatomic) UIViewController *rootViewController;
@property (atomic) BOOL isSAEInBackground;
@property (atomic) UIApplicationState reportedApplicationState;
@end
@ -33,6 +34,8 @@ NS_ASSUME_NONNULL_BEGIN
_rootViewController = rootViewController;
self.reportedApplicationState = UIApplicationStateInactive;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(extensionHostDidBecomeActive:)
name:NSExtensionHostDidBecomeActiveNotification
@ -66,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
self.isSAEInBackground = NO;
self.reportedApplicationState = UIApplicationStateActive;
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidBecomeActiveNotification object:nil];
}
@ -75,6 +78,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAssertIsOnMainThread();
self.reportedApplicationState = UIApplicationStateInactive;
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[DDLog flushLog];
@ -88,7 +93,7 @@ NS_ASSUME_NONNULL_BEGIN
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[DDLog flushLog];
self.isSAEInBackground = YES;
self.reportedApplicationState = UIApplicationStateBackground;
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationDidEnterBackgroundNotification object:nil];
}
@ -99,7 +104,7 @@ NS_ASSUME_NONNULL_BEGIN
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
self.isSAEInBackground = NO;
self.reportedApplicationState = UIApplicationStateInactive;
[NSNotificationCenter.defaultCenter postNotificationName:OWSApplicationWillEnterForegroundNotification object:nil];
}
@ -143,13 +148,12 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)isInBackground
{
return self.isSAEInBackground;
return self.reportedApplicationState == UIApplicationStateBackground;
}
- (UIApplicationState)mainApplicationState
- (BOOL)isAppForegroundAndActive
{
OWSFail(@"%@ called %s.", self.logTag, __PRETTY_FUNCTION__);
return UIApplicationStateBackground;
return self.reportedApplicationState == UIApplicationStateActive;
}
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:

Loading…
Cancel
Save