Przeglądaj źródła

Integrate sessionID from SessionsSDK into FireperfSDK (#10711)

Leo Zhan 3 lat temu
rodzic
commit
6d0c3635a8

+ 2 - 1
FirebasePerformance/CHANGELOG.md

@@ -1,5 +1,6 @@
 # Unreleased
-- [added] Added dependency on Firebase Sessions SDK to power future metrics and debugging features in Performance Monitoring
+- [added] Added dependency on Firebase Sessions SDK to power future metrics and debugging features in Performance Monitoring.
+- [changed] Changed definition of sessions, as Performance Monitoring now depends on the new Firebase Sessions SDK.
 
 # 9.3.0
 - [changed] Update the console logging URL to troubleshooting page.

+ 0 - 3
FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.m

@@ -257,9 +257,6 @@ NSString *const kFPRAppCounterNameActivePrewarm = @"_fsapc";
       }
     });
   }
-
-  // Let the session manager to start tracking app activity changes.
-  [[FPRSessionManager sharedInstance] startTrackingAppStateChanges];
 }
 
 /**

+ 1 - 1
FirebasePerformance/Sources/AppActivity/FPRSessionDetails.h

@@ -31,7 +31,7 @@ typedef NS_OPTIONS(NSUInteger, FPRSessionOptions) {
 @property(nonatomic, readonly) FPRSessionOptions options;
 
 /* Length of the session in minutes. */
-@property(nonatomic, readonly) NSUInteger sessionLengthInMinutes;
+- (NSUInteger)sessionLengthInMinutesFromDate:(nonnull NSDate *)now;
 
 /**
  * Creates an instance of FPRSessionDetails with the provided sessionId and the list of available

+ 2 - 2
FirebasePerformance/Sources/AppActivity/FPRSessionDetails.m

@@ -40,8 +40,8 @@
   return detailsCopy;
 }
 
-- (NSUInteger)sessionLengthInMinutes {
-  NSTimeInterval sessionLengthInSeconds = ABS([self.sessionCreationTime timeIntervalSinceNow]);
+- (NSUInteger)sessionLengthInMinutesFromDate:(NSDate *)now {
+  NSTimeInterval sessionLengthInSeconds = ABS([now timeIntervalSinceDate:self.sessionCreationTime]);
   return (NSUInteger)(sessionLengthInSeconds / 60);
 }
 

+ 17 - 3
FirebasePerformance/Sources/AppActivity/FPRSessionManager+Private.h

@@ -15,20 +15,34 @@
 #import <Foundation/Foundation.h>
 
 #import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
+#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
 /** This extension should only be used for testing. */
 @interface FPRSessionManager ()
 
+@property(nonatomic) FPRGaugeManager *gaugeManager;
+
 /** The current active session managed by the session manager. Modifiable for unit tests */
 @property(atomic, nullable, readwrite) FPRSessionDetails *sessionDetails;
 
 /**
- * Checks if the currently active session is beyond maximum allowed time. If so renew the session,
- * else no-op.
+ * Creates an instance of FPRSesssionManager with the notification center provided. All the
+ * notifications from the session manager will sent using this notification center.
+ *
+ * @param gaugeManager Gauge manager used by the session manager to work with gauges.
+ * @param notificationCenter Notification center with which the session manager with be initialized.
+ * @return Returns an instance of the session manager.
+ */
+- (FPRSessionManager *)initWithGaugeManager:(FPRGaugeManager *)gaugeManager
+                         notificationCenter:(NSNotificationCenter *)notificationCenter;
+
+/**
+ * Checks if the currently active session is beyond maximum allowed time for gauge-collection. If so
+ * stop gauges, else no-op.
  */
-- (void)renewSessionIdIfRunningTooLong;
+- (void)stopGaugesIfRunningTooLong;
 
 @end
 

+ 4 - 4
FirebasePerformance/Sources/AppActivity/FPRSessionManager.h

@@ -46,9 +46,9 @@ NS_EXTENSION_UNAVAILABLE("Firebase Performance is not supported for extensions."
 
 - (nullable instancetype)init NS_UNAVAILABLE;
 
-/**
- * Starts tracking the application state changes to begin session ID state changes.
- */
-- (void)startTrackingAppStateChanges;
+- (void)updateSessionId:(nonnull NSString *)sessionIdString;
+
+// Collects all the enabled gauge metrics once.
+- (void)collectAllGaugesOnce;
 
 @end

+ 26 - 50
FirebasePerformance/Sources/AppActivity/FPRSessionManager.m

@@ -17,7 +17,6 @@
 
 #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
 #import "FirebasePerformance/Sources/FPRConsoleLogger.h"
-#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
 
 #import <UIKit/UIKit.h>
 
@@ -28,17 +27,6 @@ NSString *const kFPRSessionIdNotificationKey = @"kFPRSessionIdNotificationKey";
 
 @property(nonatomic, readwrite) NSNotificationCenter *sessionNotificationCenter;
 
-@property(nonatomic) BOOL trackingApplicationStateChanges;
-
-/**
- * Creates an instance of FPRSesssionManager with the notification center provided. All the
- * notifications from the session manager will sent using this notification center.
- *
- * @param notificationCenter Notification center with which the session manager with be initialized.
- * @return Returns an instance of the session manager.
- */
-- (instancetype)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter;
-
 @end
 
 @implementation FPRSessionManager
@@ -48,60 +36,52 @@ NSString *const kFPRSessionIdNotificationKey = @"kFPRSessionIdNotificationKey";
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
     NSNotificationCenter *notificationCenter = [[NSNotificationCenter alloc] init];
-    instance = [[FPRSessionManager alloc] initWithNotificationCenter:notificationCenter];
+    FPRGaugeManager *gaugeManager = [FPRGaugeManager sharedInstance];
+    instance = [[FPRSessionManager alloc] initWithGaugeManager:gaugeManager
+                                            notificationCenter:notificationCenter];
   });
   return instance;
 }
 
-- (FPRSessionManager *)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter {
+- (FPRSessionManager *)initWithGaugeManager:(FPRGaugeManager *)gaugeManager
+                         notificationCenter:(NSNotificationCenter *)notificationCenter {
   self = [super init];
   if (self) {
+    _gaugeManager = gaugeManager;
     _sessionNotificationCenter = notificationCenter;
-    _trackingApplicationStateChanges = NO;
-    [self updateSessionId:nil];
+    // Empty string is immediately replaced when FirebaseCore runs Fireperf's
+    // FIRComponentCreationBlock, because in the creation block we register Fireperf with Sessions,
+    // and the registration function immediately propagates real sessionId. This is at an early time
+    // in initialization that any trace is yet to be created.
+    _sessionDetails = [[FPRSessionDetails alloc] initWithSessionId:@""
+                                                           options:FPRSessionOptionsNone];
   }
   return self;
 }
 
-- (void)startTrackingAppStateChanges {
-  if (!self.trackingApplicationStateChanges) {
-    // Starts tracking the application life cycle events during which the session Ids change.
-    [[NSNotificationCenter defaultCenter] addObserver:self
-                                             selector:@selector(updateSessionId:)
-                                                 name:UIApplicationWillEnterForegroundNotification
-                                               object:[UIApplication sharedApplication]];
-    self.trackingApplicationStateChanges = YES;
-  }
-}
-
-- (void)renewSessionIdIfRunningTooLong {
+- (void)stopGaugesIfRunningTooLong {
   NSUInteger maxSessionLength = [[FPRConfigurations sharedInstance] maxSessionLengthInMinutes];
-  if (self.sessionDetails.sessionLengthInMinutes > maxSessionLength) {
-    [self updateSessionId:nil];
+  if ([self.sessionDetails sessionLengthInMinutesFromDate:[NSDate date]] >= maxSessionLength) {
+    [self.gaugeManager stopCollectingGauges:FPRGaugeCPU | FPRGaugeMemory];
   }
 }
 
 /**
- * Updates the sessionId on the arrival of a notification.
+ * Stops current session, and create a new session with new session id.
  *
- * @param notification Notification received.
+ * @param sessionIdString New session id.
  */
-- (void)updateSessionId:(NSNotification *)notification {
-  NSUUID *uuid = [NSUUID UUID];
-  NSString *sessionIdString = [uuid UUIDString];
-  sessionIdString = [sessionIdString stringByReplacingOccurrencesOfString:@"-" withString:@""];
-  sessionIdString = [sessionIdString lowercaseString];
-
+- (void)updateSessionId:(NSString *)sessionIdString {
   FPRSessionOptions sessionOptions = FPRSessionOptionsNone;
-  FPRGaugeManager *gaugeManager = [FPRGaugeManager sharedInstance];
   if ([self isGaugeCollectionEnabledForSessionId:sessionIdString]) {
-    [gaugeManager startCollectingGauges:FPRGaugeCPU | FPRGaugeMemory forSessionId:sessionIdString];
+    [self.gaugeManager startCollectingGauges:FPRGaugeCPU | FPRGaugeMemory
+                                forSessionId:sessionIdString];
     sessionOptions = FPRSessionOptionsGauges;
   } else {
-    [gaugeManager stopCollectingGauges:FPRGaugeCPU | FPRGaugeMemory];
+    [self.gaugeManager stopCollectingGauges:FPRGaugeCPU | FPRGaugeMemory];
   }
 
-  FPRLogDebug(kFPRSessionId, @"Session Id generated - %@", sessionIdString);
+  FPRLogDebug(kFPRSessionId, @"Session Id changed - %@", sessionIdString);
   FPRSessionDetails *sessionInfo = [[FPRSessionDetails alloc] initWithSessionId:sessionIdString
                                                                         options:sessionOptions];
   self.sessionDetails = sessionInfo;
@@ -113,6 +93,10 @@ NSString *const kFPRSessionIdNotificationKey = @"kFPRSessionIdNotificationKey";
                                               userInfo:[userInfo copy]];
 }
 
+- (void)collectAllGaugesOnce {
+  [self.gaugeManager collectAllGauges];
+}
+
 /**
  * Checks if the provided sessionId can have gauge data collection enabled.
  *
@@ -126,12 +110,4 @@ NSString *const kFPRSessionIdNotificationKey = @"kFPRSessionIdNotificationKey";
   return sessionsEnabled;
 }
 
-- (void)dealloc {
-  if (self.trackingApplicationStateChanges) {
-    [[NSNotificationCenter defaultCenter] removeObserver:self
-                                                    name:UIApplicationDidBecomeActiveNotification
-                                                  object:[UIApplication sharedApplication]];
-  }
-}
-
 @end

+ 2 - 2
FirebasePerformance/Sources/FPRClient.m

@@ -268,7 +268,7 @@
   });
 
   // Check and update the sessionID if the session is running for too long.
-  [[FPRSessionManager sharedInstance] renewSessionIdIfRunningTooLong];
+  [[FPRSessionManager sharedInstance] stopGaugesIfRunningTooLong];
 }
 
 - (void)processAndLogEvent:(firebase_perf_v1_PerfMetric)event {
@@ -360,7 +360,7 @@
 #pragma mark - FIRSessionsSubscriber
 
 - (void)onSessionChanged:(FIRSessionDetails *_Nonnull)session {
-  FPRLogDebug(kFPRSessionId, @"Session ID changed: %@", session.sessionId);
+  [[FPRSessionManager sharedInstance] updateSessionId:session.sessionId];
 }
 
 - (BOOL)isDataCollectionEnabled {

+ 2 - 2
FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.m

@@ -194,7 +194,7 @@ NSString *const kFPRNetworkTracePropertyName = @"fpr_networkTrace";
 
 - (void)start {
   if (!self.traceCompleted) {
-    [[FPRGaugeManager sharedInstance] collectAllGauges];
+    [[FPRSessionManager sharedInstance] collectAllGaugesOnce];
     self.traceStarted = YES;
     self.backgroundActivityTracker = [[FPRTraceBackgroundActivityTracker alloc] init];
     [self checkpointState:FPRNetworkTraceCheckpointStateInitiated];
@@ -254,7 +254,7 @@ NSString *const kFPRNetworkTracePropertyName = @"fpr_networkTrace";
     [self checkpointState:FPRNetworkTraceCheckpointStateResponseCompleted];
 
     // Send the network trace for logging.
-    [[FPRGaugeManager sharedInstance] collectAllGauges];
+    [[FPRSessionManager sharedInstance] collectAllGaugesOnce];
     [[FPRClient sharedInstance] logNetworkTrace:self];
 
     self.traceCompleted = YES;

+ 2 - 2
FirebasePerformance/Sources/Timer/FIRTrace.m

@@ -136,7 +136,7 @@
 - (void)start {
   if (![self isTraceStarted]) {
     if (!self.isStage) {
-      [[FPRGaugeManager sharedInstance] collectAllGauges];
+      [[FPRSessionManager sharedInstance] collectAllGaugesOnce];
     }
     self.startTime = [NSDate date];
     self.backgroundActivityTracker = [[FPRTraceBackgroundActivityTracker alloc] init];
@@ -169,7 +169,7 @@
     self.stopTime = [NSDate date];
     [self.fprClient logTrace:self];
     if (!self.isStage) {
-      [[FPRGaugeManager sharedInstance] collectAllGauges];
+      [[FPRSessionManager sharedInstance] collectAllGaugesOnce];
     }
   } else {
     FPRLogError(kFPRTraceNotStarted,

+ 5 - 13
FirebasePerformance/Tests/Unit/FPRNetworkTraceTest.m

@@ -14,6 +14,7 @@
 
 #import <XCTest/XCTest.h>
 
+#import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
 #import "FirebasePerformance/Sources/Common/FPRConstants.h"
 #import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
 #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
@@ -437,6 +438,7 @@
 
 /** Validates that every trace contains a session Id. */
 - (void)testSessionId {
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId"];
   FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:self.testURLRequest];
   [trace start];
   [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
@@ -451,10 +453,6 @@
   NSString *string = @"Successful response";
   NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
 
-  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
-                               object:[UIApplication sharedApplication]];
-
   [trace didReceiveData:data];
   [trace didCompleteRequestWithResponse:response error:nil];
   XCTAssertNotNil(trace.sessions);
@@ -463,20 +461,14 @@
 
 /** Validates if a trace contains multiple session Ids on changing app state. */
 - (void)testMultipleSessionIds {
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId"];
   FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:self.testURLRequest];
   [trace start];
   [trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
   [trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
 
-  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
-                               object:[UIApplication sharedApplication]];
-  [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
-                               object:[UIApplication sharedApplication]];
-  [defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                               object:[UIApplication sharedApplication]];
-  [defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                               object:[UIApplication sharedApplication]];
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId2"];
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId3"];
 
   NSDictionary<NSString *, NSString *> *headerFields = @{@"Content-Type" : @"text/json"};
   NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:self.testURLRequest.URL

+ 4 - 2
FirebasePerformance/Tests/Unit/FPRSessionDetailsTest.m

@@ -34,9 +34,11 @@
   FPRSessionDetails *details = [[FPRSessionDetails alloc] initWithSessionId:@"random"
                                                                     options:FPRSessionOptionsNone];
   FPRSessionDetails *detailsCopy = [details copy];
+  NSDate *now = [NSDate date];
   XCTAssertEqual(details.sessionId, detailsCopy.sessionId);
   XCTAssertEqual(details.options, detailsCopy.options);
-  XCTAssertEqual(details.sessionLengthInMinutes, detailsCopy.sessionLengthInMinutes);
+  XCTAssertEqual([details sessionLengthInMinutesFromDate:now],
+                 [detailsCopy sessionLengthInMinutesFromDate:now]);
   XCTAssertNotNil(details);
 }
 
@@ -46,7 +48,7 @@
                                                                     options:FPRSessionOptionsNone];
   XCTAssertEqual(details.sessionId, @"random");
   XCTAssertEqual(details.options, FPRSessionOptionsNone);
-  XCTAssertEqual(details.sessionLengthInMinutes, 0);
+  XCTAssertEqual([details sessionLengthInMinutesFromDate:[NSDate date]], 0);
 }
 
 /** Validates that the session details equality with another object. */

+ 69 - 54
FirebasePerformance/Tests/Unit/FPRSessionManagerTest.m

@@ -16,17 +16,31 @@
 
 #import "FirebasePerformance/Sources/AppActivity/FPRSessionManager+Private.h"
 #import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
-
-#import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
+#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
+#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager+Private.h"
 
 #import <OCMock/OCMock.h>
 
+NSString *const testSessionId = @"testSessionId";
+
 @interface FPRSessionManagerTest : XCTestCase
 
+@property FPRSessionManager *instance;
+
+@property FPRGaugeManager *gaugeManager;
+
 @end
 
 @implementation FPRSessionManagerTest
 
+- (void)setUp {
+  [super setUp];
+  NSNotificationCenter *notificationCenter = [[NSNotificationCenter alloc] init];
+  _gaugeManager = [[FPRGaugeManager alloc] initWithGauges:FPRGaugeCPU | FPRGaugeMemory];
+  _instance = [[FPRSessionManager alloc] initWithGaugeManager:_gaugeManager
+                                           notificationCenter:notificationCenter];
+}
+
 /** Validate the instance gets created and it is a singleton. */
 - (void)testInstanceCreation {
   FPRSessionManager *instance = [FPRSessionManager sharedInstance];
@@ -34,74 +48,77 @@
   XCTAssertEqual(instance, [FPRSessionManager sharedInstance]);
 }
 
-/** Validate that valid sessionId always exists. */
-- (void)testSessionIdExistance {
-  FPRSessionManager *instance = [FPRSessionManager sharedInstance];
-  [instance startTrackingAppStateChanges];
-
-  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-  [notificationCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                                    object:[UIApplication sharedApplication]];
+/** Validate that gauge collection does not change when calling renew method immediately. */
+- (void)testGaugeDoesNotStopBeforeMaxDuration {
+  FPRSessionManager *manager =
+      [[FPRSessionManager alloc] initWithGaugeManager:self.gaugeManager
+                                   notificationCenter:[NSNotificationCenter defaultCenter]];
+  id mockInstance = [OCMockObject partialMockForObject:[FPRConfigurations sharedInstance]];
+  OCMStub([mockInstance sessionsSamplingPercentage]).andReturn(100);
+  [manager updateSessionId:testSessionId];
+  XCTAssertTrue(manager.gaugeManager.activeGauges > 0);
 
-  XCTAssertNotNil(instance.sessionDetails.sessionId);
+  OCMStub([mockInstance maxSessionLengthInMinutes]).andReturn(5);
+  XCTAssertTrue(manager.gaugeManager.activeGauges > 0);
 
-  NSString *lowercaseSessionId = [instance.sessionDetails.sessionId lowercaseString];
-  XCTAssertEqualObjects(lowercaseSessionId, instance.sessionDetails.sessionId);
+  [mockInstance stopMocking];
 }
 
-/** Validate that sessionId does not change when calling renew method immediately. */
-- (void)testSessionIdNotGettingRenewed {
-  FPRSessionManager *instance = [FPRSessionManager sharedInstance];
-  [instance startTrackingAppStateChanges];
-  NSString *sessionId = instance.sessionDetails.sessionId;
-  [instance renewSessionIdIfRunningTooLong];
-  XCTAssertEqualObjects(sessionId, instance.sessionDetails.sessionId);
+/** Validate that gauge collection stops when calling renew method after max duration reached. */
+- (void)testGaugeStopsAfterMaxDuration {
+  FPRSessionManager *manager =
+      [[FPRSessionManager alloc] initWithGaugeManager:self.gaugeManager
+                                   notificationCenter:[NSNotificationCenter defaultCenter]];
+  id mockInstance = [OCMockObject partialMockForObject:[FPRConfigurations sharedInstance]];
+  OCMStub([mockInstance sessionsSamplingPercentage]).andReturn(100);
+  [manager updateSessionId:testSessionId];
+  XCTAssertTrue(manager.gaugeManager.activeGauges > 0);
+
+  XCTAssertEqual(manager.sessionDetails.options & FPRSessionOptionsGauges, FPRSessionOptionsGauges);
+  OCMStub([mockInstance maxSessionLengthInMinutes]).andReturn(0);
+  [manager stopGaugesIfRunningTooLong];
+  XCTAssertEqual(manager.gaugeManager.activeGauges, 0);
+
+  [mockInstance stopMocking];
 }
 
-/** Validate that sessionId changes on application state changes. */
-- (void)testSessionIdUpdation {
-  FPRSessionManager *instance = [FPRSessionManager sharedInstance];
-  [instance startTrackingAppStateChanges];
-  NSString *sessionId = instance.sessionDetails.sessionId;
-  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-  [notificationCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                                    object:[UIApplication sharedApplication]];
-  XCTAssertNotEqual(sessionId, instance.sessionDetails.sessionId);
+/** Validate that sessionId changes on new session. */
+- (void)testUpdateSessionId {
+  [self.instance updateSessionId:testSessionId];
+  NSString *sessionId = self.instance.sessionDetails.sessionId;
+  [self.instance updateSessionId:@"testSessionId2"];
+  XCTAssertNotEqual(sessionId, self.instance.sessionDetails.sessionId);
 }
 
 /** Validate that sessionId changes sends notifications. */
-- (void)testSessionIdUpdationThrowsNotification {
-  FPRSessionManager *instance = [FPRSessionManager sharedInstance];
-  [instance startTrackingAppStateChanges];
-  NSString *sessionId = instance.sessionDetails.sessionId;
+- (void)testUpdateSessionIdPostsNotification {
+  [self.instance updateSessionId:testSessionId];
+  NSString *sessionId = self.instance.sessionDetails.sessionId;
 
   __block BOOL receivedNotification = NO;
-  [instance.sessionNotificationCenter addObserverForName:kFPRSessionIdUpdatedNotification
-                                                  object:instance
-                                                   queue:[NSOperationQueue mainQueue]
-                                              usingBlock:^(NSNotification *note) {
-                                                receivedNotification = YES;
-                                              }];
+  [self.instance.sessionNotificationCenter addObserverForName:kFPRSessionIdUpdatedNotification
+                                                       object:self.instance
+                                                        queue:[NSOperationQueue mainQueue]
+                                                   usingBlock:^(NSNotification *note) {
+                                                     receivedNotification = YES;
+                                                   }];
 
-  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-  [notificationCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                                    object:[UIApplication sharedApplication]];
+  [self.instance updateSessionId:@"testSessionId2"];
 
   XCTAssertTrue(receivedNotification);
-  XCTAssertNotEqual(sessionId, instance.sessionDetails.sessionId);
+  XCTAssertNotEqual(sessionId, self.instance.sessionDetails.sessionId);
 }
 
 /** Validate that sessionId changes sends notifications with the session details. */
-- (void)testSessionIdUpdationSendsNotificationWithSessionDetails {
-  FPRSessionManager *instance = [FPRSessionManager sharedInstance];
-  [instance startTrackingAppStateChanges];
-  NSString *sessionId = instance.sessionDetails.sessionId;
+- (void)testUpdateSessionIdPostsNotificationWithSessionDetails {
+  [self.instance updateSessionId:testSessionId];
+  NSString *sessionId = self.instance.sessionDetails.sessionId;
 
   __block BOOL containsSessionDetails = NO;
   __block FPRSessionDetails *updatedSessionDetails = nil;
-  [instance.sessionNotificationCenter
+  [self.instance.sessionNotificationCenter
       addObserverForName:kFPRSessionIdUpdatedNotification
-                  object:instance
+                  object:self.instance
                    queue:[NSOperationQueue mainQueue]
               usingBlock:^(NSNotification *note) {
                 NSDictionary<NSString *, FPRSessionDetails *> *userInfo = note.userInfo;
@@ -113,13 +130,11 @@
                 }
               }];
 
-  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
-  [notificationCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                                    object:[UIApplication sharedApplication]];
+  [self.instance updateSessionId:@"testSessionId2"];
 
   XCTAssertTrue(containsSessionDetails);
-  XCTAssertNotEqual(sessionId, instance.sessionDetails.sessionId);
-  XCTAssertEqual(updatedSessionDetails.sessionId, instance.sessionDetails.sessionId);
+  XCTAssertNotEqual(sessionId, self.instance.sessionDetails.sessionId);
+  XCTAssertEqual(updatedSessionDetails.sessionId, self.instance.sessionDetails.sessionId);
 }
 
 @end

+ 5 - 15
FirebasePerformance/Tests/Unit/Timer/FIRTraceTest.m

@@ -15,6 +15,7 @@
 #import <XCTest/XCTest.h>
 
 #import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
+#import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
 #import "FirebasePerformance/Sources/Common/FPRConstants.h"
 #import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
 #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
@@ -722,13 +723,9 @@
 
 /** Validates if every trace contains a session Id. */
 - (void)testSessionId {
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId"];
   FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
   [trace start];
-
-  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
-                               object:[UIApplication sharedApplication]];
-
   [trace stop];
   XCTAssertNotNil(trace.sessions);
   XCTAssertTrue(trace.sessions.count > 0);
@@ -736,18 +733,11 @@
 
 /** Validates if every trace contains multiple session Ids on changing app state. */
 - (void)testMultipleSessionIds {
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId"];
   FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
   [trace start];
-  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
-  [defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
-                               object:[UIApplication sharedApplication]];
-  [defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
-                               object:[UIApplication sharedApplication]];
-  [defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                               object:[UIApplication sharedApplication]];
-
-  [defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
-                               object:[UIApplication sharedApplication]];
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId2"];
+  [[FPRSessionManager sharedInstance] updateSessionId:@"testSessionId3"];
 
   XCTestExpectation *expectation = [self expectationWithDescription:@"Expectation - Wait for 2s"];
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)),