|
18 | 18 | #import <UIKit/UIKit.h>
|
19 | 19 |
|
20 | 20 | #import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
|
| 21 | +#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h" |
21 | 22 | #import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeCollector+Private.h"
|
22 | 23 | #import "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
|
23 | 24 | #import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeCollector+Private.h"
|
24 | 25 | #import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
|
25 | 26 | #import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
|
26 | 27 |
|
27 |
| -#import <GoogleUtilities/GULAppEnvironmentUtil.h> |
28 |
| - |
29 | 28 | static NSDate *appStartTime = nil;
|
30 | 29 | static NSDate *doubleDispatchTime = nil;
|
31 | 30 | static NSDate *applicationDidFinishLaunchTime = nil;
|
32 | 31 | static NSTimeInterval gAppStartMaxValidDuration = 60 * 60; // 60 minutes.
|
33 | 32 | static FPRCPUGaugeData *gAppStartCPUGaugeData = nil;
|
34 | 33 | static FPRMemoryGaugeData *gAppStartMemoryGaugeData = nil;
|
| 34 | +static BOOL isActivePrewarm = NO; |
35 | 35 |
|
36 | 36 | NSString *const kFPRAppStartTraceName = @"_as";
|
37 | 37 | NSString *const kFPRAppStartStageNameTimeToUI = @"_astui";
|
@@ -86,6 +86,10 @@ + (void)load {
|
86 | 86 | });
|
87 | 87 | }
|
88 | 88 |
|
| 89 | + // When an app is prewarmed, Apple sets env variable ActivePrewarm to 1, then the env variable is |
| 90 | + // deleted after didFinishLaunching |
| 91 | + isActivePrewarm = [NSProcessInfo.processInfo.environment[@"ActivePrewarm"] isEqualToString:@"1"]; |
| 92 | + |
89 | 93 | gAppStartCPUGaugeData = fprCollectCPUMetric();
|
90 | 94 | gAppStartMemoryGaugeData = fprCollectMemoryMetric();
|
91 | 95 | [[NSNotificationCenter defaultCenter] addObserver:self
|
@@ -155,20 +159,18 @@ - (FIRTrace *)activeTrace {
|
155 | 159 | }
|
156 | 160 |
|
157 | 161 | /**
|
158 |
| - * Checks if prewarming is available for the platform on current device. |
159 |
| - * It is available when running iOS 15 and above. |
| 162 | + * Checks if the prewarming feature is available on the current device. |
160 | 163 | *
|
161 |
| - * @return true if the platform could prewarm apps on the current device |
| 164 | + * @return true if the OS could prewarm apps on the current device |
162 | 165 | */
|
163 |
| -+ (BOOL)isPrewarmAvailable { |
164 |
| - if (![[[GULAppEnvironmentUtil applePlatform] lowercaseString] isEqualToString:@"ios"]) { |
165 |
| - return NO; |
166 |
| - } |
167 |
| - NSString *systemVersion = [GULAppEnvironmentUtil systemVersion]; |
168 |
| - if ([systemVersion length] == 0) { |
169 |
| - return NO; |
| 166 | +- (BOOL)isPrewarmAvailable { |
| 167 | + BOOL canPrewarm = NO; |
| 168 | + // Guarding for double dispatch which does not work below iOS 13, and 0.1% of app start also show |
| 169 | + // signs of prewarming on iOS 14 go/paste/5533761933410304 |
| 170 | + if (@available(iOS 13, *)) { |
| 171 | + canPrewarm = YES; |
170 | 172 | }
|
171 |
| - return [systemVersion compare:@"15" options:NSNumericSearch] != NSOrderedAscending; |
| 173 | + return canPrewarm; |
172 | 174 | }
|
173 | 175 |
|
174 | 176 | /**
|
@@ -200,15 +202,13 @@ - (BOOL)isDoubleDispatchEnabled {
|
200 | 202 | Checks if the current app start is a prewarmed app start
|
201 | 203 | */
|
202 | 204 | - (BOOL)isApplicationPreWarmed {
|
203 |
| - if (![FPRAppActivityTracker isPrewarmAvailable]) { |
| 205 | + if (![self isPrewarmAvailable]) { |
204 | 206 | return NO;
|
205 | 207 | }
|
206 | 208 |
|
207 | 209 | BOOL isPrewarmed = NO;
|
208 | 210 |
|
209 |
| - NSDictionary<NSString *, NSString *> *environment = [NSProcessInfo processInfo].environment; |
210 |
| - BOOL activePrewarmFlagValue = [environment[@"ActivePrewarm"] boolValue]; |
211 |
| - if (activePrewarmFlagValue == YES) { |
| 211 | + if (isActivePrewarm == YES) { |
212 | 212 | isPrewarmed = isPrewarmed || [self isActivePrewarmEnabled];
|
213 | 213 | [self.activeTrace incrementMetric:kFPRAppCounterNameActivePrewarm byInt:1];
|
214 | 214 | } else {
|
|
0 commit comments