Skip to content
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
64 changes: 61 additions & 3 deletions Example/Core/Tests/FIRAppTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
#import "FIRTestCase.h"
#import "FIRTestComponents.h"

#import <FirebaseCoreDiagnosticsInterop/FIRCoreDiagnosticsData.h>
#import <FirebaseCoreDiagnosticsInterop/FIRCoreDiagnosticsInterop.h>

#import <FirebaseCore/FIRAnalyticsConfiguration.h>
#import <FirebaseCore/FIRAppInternal.h>
#import <FirebaseCore/FIRCoreDiagnosticsConnector.h>
#import <FirebaseCore/FIROptionsInternal.h>

NSString *const kFIRTestAppName1 = @"test_app_name_1";
Expand Down Expand Up @@ -53,6 +51,7 @@ @interface FIRAppTest : FIRTestCase

@property(nonatomic) id appClassMock;
@property(nonatomic) id observerMock;
@property(nonatomic) id mockCoreDiagnosticsConnector;
@property(nonatomic) NSNotificationCenter *notificationCenter;

@end
Expand All @@ -65,6 +64,11 @@ - (void)setUp {
[FIRApp resetApps];
_appClassMock = OCMClassMock([FIRApp class]);
_observerMock = OCMObserverMock();
_mockCoreDiagnosticsConnector = OCMClassMock([FIRCoreDiagnosticsConnector class]);

OCMStub(ClassMethod([self.mockCoreDiagnosticsConnector logCoreTelemetryWithOptions:[OCMArg any]]))
.andDo(^(NSInvocation *invocation){
});

// TODO: Remove all usages of defaultCenter in Core, then we can instantiate an instance here to
// inject instead of using defaultCenter.
Expand All @@ -76,6 +80,7 @@ - (void)tearDown {
[_notificationCenter removeObserver:_observerMock];
_observerMock = nil;
_notificationCenter = nil;
_mockCoreDiagnosticsConnector = nil;

[super tearDown];
}
Expand Down Expand Up @@ -730,6 +735,24 @@ - (void)testRegisteringNonConformingLibrary {
XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"InvalidLibrary`/1.0.0"]);
}

#pragma mark - Core Diagnostics

- (void)testCoreDiagnosticsLoggedWhenFIRAppIsConfigured {
[self expectCoreDiagnosticsDataLogWithOptions:[self appOptions]];
[self createConfiguredAppWithName:NSStringFromSelector(_cmd)];
OCMVerifyAll(self.mockCoreDiagnosticsConnector);
}

- (void)testCoreDiagnosticsLoggedWhenAppDidBecomeActive {
FIRApp *app = [self createConfiguredAppWithName:NSStringFromSelector(_cmd)];
[self expectCoreDiagnosticsDataLogWithOptions:app.options];

[self.notificationCenter postNotificationName:[self appDidBecomeActiveNotificationName]
object:nil];

OCMVerifyAll(self.mockCoreDiagnosticsConnector);
}

#pragma mark - private

- (void)expectNotificationForObserver:(id)observer
Expand All @@ -749,4 +772,39 @@ - (void)expectNotificationForObserver:(id)observer
};
}

- (void)expectCoreDiagnosticsDataLogWithOptions:(nullable FIROptions *)expectedOptions {
[self.mockCoreDiagnosticsConnector stopMocking];
self.mockCoreDiagnosticsConnector = nil;
self.mockCoreDiagnosticsConnector = OCMClassMock([FIRCoreDiagnosticsConnector class]);

OCMExpect(ClassMethod([self.mockCoreDiagnosticsConnector
logCoreTelemetryWithOptions:[OCMArg checkWithBlock:^BOOL(FIROptions *options) {
if (!expectedOptions) {
return YES;
}
return [options.googleAppID isEqualToString:expectedOptions.googleAppID] &&
[options.GCMSenderID isEqualToString:expectedOptions.GCMSenderID];
}]]));
}

- (NSNotificationName)appDidBecomeActiveNotificationName {
#if TARGET_OS_IOS || TARGET_OS_TV
return UIApplicationDidBecomeActiveNotification;
#endif

#if TARGET_OS_OSX
return NSApplicationDidBecomeActiveNotification;
#endif
}

- (FIRApp *)createConfiguredAppWithName:(NSString *)name {
FIROptions *options = [self appOptions];
[FIRApp configureWithName:name options:options];
return [FIRApp appNamed:name];
}

- (FIROptions *)appOptions {
return [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID GCMSenderID:kGCMSenderID];
}

@end
47 changes: 42 additions & 5 deletions Firebase/Core/FIRApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@

#include <sys/utsname.h>

#import "FIRApp.h"
#if __has_include(<UIKit/UIKit.h>)
#import <UIKit/UIKit.h>
#endif

#if __has_include(<AppKit/AppKit.h>)
#import <AppKit/AppKit.h>
#endif

#import <FirebaseCoreDiagnosticsInterop/FIRCoreDiagnosticsData.h>
#import "FIRApp.h"

#import "Private/FIRAnalyticsConfiguration.h"
#import "Private/FIRAppInternal.h"
Expand Down Expand Up @@ -283,15 +289,17 @@ - (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)opti
return self;
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (BOOL)configureCore {
[self checkExpectedBundleID];
if (![self isAppIDValid]) {
return NO;
}

if ([self isDataCollectionDefaultEnabled]) {
[FIRCoreDiagnosticsConnector logConfigureCoreWithOptions:_options];
}
[self logCoreTelemetryIfEnabled];

#if TARGET_OS_IOS
// Initialize the Analytics once there is a valid options under default app. Analytics should
Expand All @@ -316,6 +324,8 @@ - (BOOL)configureCore {
}
#endif

[self subscribeForAppDidBecomeActiveNotifications];

return YES;
}

Expand Down Expand Up @@ -796,4 +806,31 @@ - (void)sendLogsWithServiceName:(NSString *)serviceName
}
#pragma clang diagnostic pop

#pragma mark - App Life Cycle
Copy link
Contributor

Choose a reason for hiding this comment

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

Just FYI, there is some lifecycle code in GDTLifecycle. I'm not sure if you want to adopt that protocol or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will be nice to reuse it. Is GoogleDataTransport meant to be a required dependency for FirebaseCore?
cc @paulb777

Copy link
Contributor

Choose a reason for hiding this comment

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

GDT won't come in if FirebaseCoreDiagnostics isn't present, so I wouldn't add a hard dependency on it.


- (void)subscribeForAppDidBecomeActiveNotifications {
#if TARGET_OS_IOS || TARGET_OS_TV
NSNotificationName notificationName = UIApplicationDidBecomeActiveNotification;
#endif

#if TARGET_OS_OSX
NSNotificationName notificationName = NSApplicationDidBecomeActiveNotification;
#endif

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidBecomeActive:)
name:notificationName
object:nil];
}

- (void)appDidBecomeActive:(NSNotification *)notification {
[self logCoreTelemetryIfEnabled];
}

- (void)logCoreTelemetryIfEnabled {
if ([self isDataCollectionDefaultEnabled]) {
[FIRCoreDiagnosticsConnector logCoreTelemetryWithOptions:_options];
}
}

@end
2 changes: 1 addition & 1 deletion Firebase/Core/FIRCoreDiagnosticsConnector.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ + (void)initialize {
}
}

+ (void)logConfigureCoreWithOptions:(FIROptions *)options {
+ (void)logCoreTelemetryWithOptions:(FIROptions *)options {
if (FIRCoreDiagnosticsImplementation) {
FIRDiagnosticsData *diagnosticsData = [[FIRDiagnosticsData alloc] init];
[diagnosticsData insertValue:@(YES) forKey:kFIRCDIsDataCollectionDefaultEnabledKey];
Expand Down
4 changes: 2 additions & 2 deletions Firebase/Core/Private/FIRCoreDiagnosticsConnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ NS_ASSUME_NONNULL_BEGIN
/** Connects FIRCore with the CoreDiagnostics library. */
@interface FIRCoreDiagnosticsConnector : NSObject

/** Logs data related to a -configureCore call.
/** Logs FirebaseCore related data.
*
* @param options The options object containing data to log.
*/
+ (void)logConfigureCoreWithOptions:(FIROptions *)options;
+ (void)logCoreTelemetryWithOptions:(FIROptions *)options;

@end

Expand Down