Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ref: Don't only update App State in the OOM tracker #2276

Merged
merged 5 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions Samples/iOS-SwiftUI/iOS-SwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */ = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why I got these changes in the project file for iOS-SwiftUI. I did open that project recently instead of iOS-Swift, I guess just opening it must've triggered something in Xcode?

isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 63AA759B1EB8AEF500D153DE;
remoteInfo = Sentry;
};
0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 63AA76651EB8CB2F00D153DE;
remoteInfo = SentryTests;
};
7B64385C26A6C0A6000D0F65 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7BB6224126A56C4E00D0E75E /* Project object */;
Expand Down Expand Up @@ -101,6 +115,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
0A94157928F6B893006A5DD1 /* Products */ = {
isa = PBXGroup;
children = (
0A94157E28F6B893006A5DD1 /* Sentry.framework */,
0A94158028F6B893006A5DD1 /* SentryTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
7B64385826A6C0A6000D0F65 /* iOS-SwiftUI-UITests */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -242,6 +265,10 @@
productRefGroup = 7BB6224A26A56C4E00D0E75E /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 0A94157928F6B893006A5DD1 /* Products */;
ProjectRef = 84D4FEA828ECD52700EDAAFE /* Sentry.xcodeproj */;
},
{
ProductGroup = 84D4FEAB28ECD52E00EDAAFE /* Products */;
ProjectRef = 84D4FEAA28ECD52E00EDAAFE /* Sentry.xcodeproj */;
Expand All @@ -256,6 +283,20 @@
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
0A94157E28F6B893006A5DD1 /* Sentry.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Sentry.framework;
remoteRef = 0A94157D28F6B893006A5DD1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
0A94158028F6B893006A5DD1 /* SentryTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = SentryTests.xctest;
remoteRef = 0A94157F28F6B893006A5DD1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
84D4FEB228ECD52E00EDAAFE /* Sentry.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
Expand Down
4 changes: 4 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
0A56DA5F28ABA01B00C400D5 /* SentryTransactionContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */; };
0A6EEADD28A657970076B469 /* UIViewRecursiveDescriptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */; };
0A8F0A392886CC70000B15F6 /* SentryPermissionsObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AABE2EE288592750057ED69 /* SentryPermissionsObserver.h */; };
0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */; };
0A9BF4E228A114940068D266 /* SentryViewHierarchyIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */; };
0A9BF4E428A114B50068D266 /* SentryViewHierarchyIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */; };
0A9BF4E928A125390068D266 /* TestSentryViewHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */; };
Expand Down Expand Up @@ -757,6 +758,7 @@
0A5370A028A3EC2400B2DCDE /* SentryViewHierarchyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewHierarchyTests.swift; sourceTree = "<group>"; };
0A56DA5E28ABA01B00C400D5 /* SentryTransactionContext+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryTransactionContext+Private.h"; path = "include/SentryTransactionContext+Private.h"; sourceTree = "<group>"; };
0A6EEADC28A657970076B469 /* UIViewRecursiveDescriptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewRecursiveDescriptionTests.swift; sourceTree = "<group>"; };
0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppStateManagerTests.swift; sourceTree = "<group>"; };
0A9BF4E128A114940068D266 /* SentryViewHierarchyIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryViewHierarchyIntegration.m; sourceTree = "<group>"; };
0A9BF4E328A114B50068D266 /* SentryViewHierarchyIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryViewHierarchyIntegration.h; path = include/SentryViewHierarchyIntegration.h; sourceTree = "<group>"; };
0A9BF4E628A123270068D266 /* TestSentryViewHierarchy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryViewHierarchy.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2400,6 +2402,7 @@
7B85BD8D24C5C3A6000A4225 /* SentryFileManagerTestExtension.swift */,
7B4C817124D1BC2B0076ACE4 /* SentryFileManager+TestProperties.h */,
7B98D7EB25FB7C4900C5A389 /* SentryAppStateTests.swift */,
0A94158128F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift */,
69BEE6F62620729E006DF9DF /* UrlSessionDelegateSpy.swift */,
7BD86ECA264A6DB5005439DB /* TestSysctl.swift */,
7B16FD012654F86B008177D3 /* SentrySysctlTests.swift */,
Expand Down Expand Up @@ -3612,6 +3615,7 @@
7B88F30224BC5C6D00ADF90A /* SentrySdkInfoTests.swift in Sources */,
7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */,
63FE721220DA66EC00CDBAE8 /* SentryCrashMach_Tests.m in Sources */,
0A94158228F6C4C2006A5DD1 /* SentryAppStateManagerTests.swift in Sources */,
7B6D98E924C6D336005502FA /* SentrySdkInfo+Equality.m in Sources */,
7BDB03BF25136A7D00BAE198 /* TestSentryDispatchQueueWrapper.swift in Sources */,
7B6438A726A70DDB000D0F65 /* UIViewControllerSentryTests.swift in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions Sources/Sentry/SentryAppStartTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ - (void)start
if (PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode) {
[self buildAppStartMeasurement];
}

# if SENTRY_HAS_UIKIT
[self.appStateManager start];
# endif
}

- (void)buildAppStartMeasurement
Expand Down Expand Up @@ -259,6 +263,10 @@ - (void)stop
[NSNotificationCenter.defaultCenter removeObserver:self
name:UIApplicationDidEnterBackgroundNotification
object:nil];

# if SENTRY_HAS_UIKIT
[self.appStateManager stop];
# endif
}

- (void)dealloc
Expand Down
143 changes: 132 additions & 11 deletions Sources/Sentry/SentryAppStateManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
#import <SentryAppStateManager.h>
#import <SentryCrashWrapper.h>
#import <SentryCurrentDateProvider.h>
#import <SentryDispatchQueueWrapper.h>
#import <SentryFileManager.h>
#import <SentryOptions.h>

#if SENTRY_HAS_UIKIT
# import <SentryInternalNotificationNames.h>
# import <SentryNSNotificationCenterWrapper.h>
# import <UIKit/UIKit.h>
#endif

Expand All @@ -20,6 +23,8 @@
@property (nonatomic, strong) SentryFileManager *fileManager;
@property (nonatomic, strong) id<SentryCurrentDateProvider> currentDate;
@property (nonatomic, strong) SentrySysctl *sysctl;
@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue;
@property (nonatomic) NSInteger startCount;

@end

Expand All @@ -30,19 +35,146 @@ - (instancetype)initWithOptions:(SentryOptions *)options
fileManager:(SentryFileManager *)fileManager
currentDateProvider:(id<SentryCurrentDateProvider>)currentDateProvider
sysctl:(SentrySysctl *)sysctl
dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
{
if (self = [super init]) {
self.options = options;
self.crashWrapper = crashWrapper;
self.fileManager = fileManager;
self.currentDate = currentDateProvider;
self.sysctl = sysctl;
self.dispatchQueue = dispatchQueueWrapper;
self.startCount = 0;
}
return self;
}

#if SENTRY_HAS_UIKIT

- (void)start
{
if (self.startCount == 0) {
[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(didBecomeActive)
name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(didBecomeActive)
name:SentryHybridSdkDidBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(willResignActive)
name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
addObserver:self
selector:@selector(willTerminate)
name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
object:nil];

[self storeCurrentAppState];
}

self.startCount += 1;
}

- (void)stop
{
if (self.startCount <= 0) {
return;
}

self.startCount -= 1;

if (self.startCount == 0) {
// Remove the observers with the most specific detail possible, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryHybridSdkDidBecomeActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
object:nil];

[NSNotificationCenter.defaultCenter
removeObserver:self
name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
object:nil];

[self deleteAppState];
}
}

- (void)dealloc
{
// In dealloc it's safe to unsubscribe for all, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
[NSNotificationCenter.defaultCenter removeObserver:self];
[self deleteAppState];
}

/**
* It is called when an app is receiving events / it is in the foreground and when we receive a
* SentryHybridSdkDidBecomeActiveNotification.
*
* This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification
* regardless of whether your app uses scenes, see
* https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive.
*/
- (void)didBecomeActive
{
[self updateAppStateInBackground:^(SentryAppState *appState) { appState.isActive = YES; }];
}

/**
* The app is about to lose focus / going to the background. This is only called when an app was
* receiving events / was is in the foreground.
*/
- (void)willResignActive
{
[self updateAppStateInBackground:^(SentryAppState *appState) { appState.isActive = NO; }];
}

- (void)willTerminate
{
// The app is terminating so it is fine to do this on the main thread.
// Furthermore, so users can manually post UIApplicationWillTerminateNotification and then call
// exit(0), to avoid getting false OOM when using exit(0), see GH-1252.
[self updateAppState:^(SentryAppState *appState) { appState.wasTerminated = YES; }];
}

- (void)updateAppStateInBackground:(void (^)(SentryAppState *))block
{
// We accept the tradeoff that the app state might not be 100% up to date over blocking the main
// thread.
[self.dispatchQueue dispatchAsyncWithBlock:^{ [self updateAppState:block]; }];
}

- (void)updateAppState:(void (^)(SentryAppState *))block
{
@synchronized(self) {
SentryAppState *appState = [self.fileManager readAppState];
if (nil != appState) {
block(appState);
[self.fileManager storeAppState:appState];
}
}
}

- (SentryAppState *)buildCurrentAppState
{
// Is the current process being traced or not? If it is a debugger is attached.
Expand Down Expand Up @@ -72,17 +204,6 @@ - (void)deleteAppState
[self.fileManager deleteAppState];
}

- (void)updateAppState:(void (^)(SentryAppState *))block
{
@synchronized(self) {
SentryAppState *appState = [self.fileManager readAppState];
if (nil != appState) {
block(appState);
[self.fileManager storeAppState:appState];
}
}
}

#endif

@end
11 changes: 6 additions & 5 deletions Sources/Sentry/SentryDependencyContainer.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ - (SentryAppStateManager *)appStateManager
if (_appStateManager == nil) {
SentryOptions *options = [[[SentrySDK currentHub] getClient] options];
_appStateManager = [[SentryAppStateManager alloc]
initWithOptions:options
crashWrapper:self.crashWrapper
fileManager:self.fileManager
currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
sysctl:[[SentrySysctl alloc] init]];
initWithOptions:options
crashWrapper:self.crashWrapper
fileManager:self.fileManager
currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
sysctl:[[SentrySysctl alloc] init]
dispatchQueueWrapper:self.dispatchQueueWrapper];
}
return _appStateManager;
}
Expand Down
Loading