Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2020 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#import <UIKit/UIKit.h>
16
 
17
#import "FirebasePerformance/Sources/Common/FPRConstants.h"
18
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
19
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
20
 
21
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags+Private.h"
22
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
23
 
24
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
25
 
26
FPRConfigName kFPRConfigDataCollectionEnabled = @"dataCollectionEnabled";
27
 
28
FPRConfigName kFPRConfigInstrumentationEnabled = @"instrumentationEnabled";
29
 
30
NSString *const kFPRConfigInstrumentationUserPreference =
31
    @"com.firebase.performanceInsrumentationEnabled";
32
NSString *const kFPRConfigInstrumentationPlistKey = @"firebase_performance_instrumentation_enabled";
33
 
34
NSString *const kFPRConfigCollectionUserPreference = @"com.firebase.performanceCollectionEnabled";
35
NSString *const kFPRConfigCollectionPlistKey = @"firebase_performance_collection_enabled";
36
 
37
NSString *const kFPRDiagnosticsUserPreference = @"FPRDiagnosticsLocal";
38
NSString *const kFPRDiagnosticsEnabledPlistKey = @"FPRDiagnosticsLocal";
39
 
40
NSString *const kFPRConfigCollectionDeactivationPlistKey =
41
    @"firebase_performance_collection_deactivated";
42
 
43
NSString *const kFPRConfigLogSource = @"com.firebase.performanceLogSource";
44
 
45
@implementation FPRConfigurations
46
 
47
static dispatch_once_t gSharedInstanceToken;
48
 
49
+ (instancetype)sharedInstance {
50
  static FPRConfigurations *instance = nil;
51
  dispatch_once(&gSharedInstanceToken, ^{
52
    FPRConfigurationSource sources = FPRConfigurationSourceRemoteConfig;
53
    instance = [[FPRConfigurations alloc] initWithSources:sources];
54
  });
55
  return instance;
56
}
57
 
58
+ (void)reset {
59
  // TODO(b/120032990): Reset the singletons that this singleton uses.
60
  gSharedInstanceToken = 0;
61
  [[NSUserDefaults standardUserDefaults]
62
      removeObjectForKey:kFPRConfigInstrumentationUserPreference];
63
  [[NSUserDefaults standardUserDefaults] removeObjectForKey:kFPRConfigCollectionUserPreference];
64
}
65
 
66
- (instancetype)initWithSources:(FPRConfigurationSource)source {
67
  self = [super init];
68
  if (self) {
69
    _sources = source;
70
    [self setupRemoteConfigFlags];
71
 
72
    // Register for notifications to update configs.
73
    [self registerForNotifications];
74
 
75
    self.FIRAppClass = [FIRApp class];
76
    self.userDefaults = [NSUserDefaults standardUserDefaults];
77
    self.infoDictionary = [NSBundle mainBundle].infoDictionary;
78
    self.mainBundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
79
    self.updateQueue = dispatch_queue_create("com.google.perf.configUpdate", DISPATCH_QUEUE_SERIAL);
80
  }
81
 
82
  return self;
83
}
84
 
85
- (void)registerForNotifications {
86
  [[NSNotificationCenter defaultCenter] addObserver:self
87
                                           selector:@selector(update)
88
                                               name:UIApplicationDidBecomeActiveNotification
89
                                             object:nil];
90
}
91
 
92
/** Searches the main bundle and the bundle from bundleForClass: info dictionaries for the key and
93
 *  returns the first result.
94
 *
95
 * @param key The key to search the info dictionaries for.
96
 * @return The first object found in the info dictionary of the main bundle and bundleForClass:.
97
 */
98
- (nullable id)objectForInfoDictionaryKey:(NSString *)key {
99
  // If the config infoDictionary has been set to a new dictionary, only use the original dictionary
100
  // instead of the new dictionary.
101
  if (self.infoDictionary != [NSBundle mainBundle].infoDictionary) {
102
    return self.infoDictionary[key];  // nullable.
103
  }
104
  NSArray<NSBundle *> *bundles = @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ];
105
  for (NSBundle *bundle in bundles) {
106
    id object = [bundle objectForInfoDictionaryKey:key];
107
    if (object) {
108
      return object;  // nonnull.
109
    }
110
  }
111
  return nil;
112
}
113
 
114
- (void)update {
115
  dispatch_async(self.updateQueue, ^{
116
    if (!self.remoteConfigFlags) {
117
      [self setupRemoteConfigFlags];
118
    }
119
    [self.remoteConfigFlags update];
120
  });
121
}
122
 
123
/**
124
 * Sets up the remote config flags instance based on 3 different factors:
125
 * 1. Is the firebase app configured?
126
 * 2. Is the remote config source enabled?
127
 * 3. If the Remote Config flags instance exists already?
128
 */
129
- (void)setupRemoteConfigFlags {
130
  if (!self.remoteConfigFlags && [self.FIRAppClass isDefaultAppConfigured] &&
131
      (self.sources & FPRConfigurationSourceRemoteConfig) == FPRConfigurationSourceRemoteConfig) {
132
    self.remoteConfigFlags = [FPRRemoteConfigFlags sharedInstance];
133
  }
134
}
135
 
136
#pragma mark - Overridden Properties
137
 
138
- (void)setDataCollectionEnabled:(BOOL)dataCollectionEnabled {
139
  [self.userDefaults setBool:dataCollectionEnabled forKey:kFPRConfigCollectionUserPreference];
140
}
141
 
142
// The data collection flag is determined by this order:
143
//   1. A plist flag for permanently disabling data collection
144
//   2. The runtime flag (NSUserDefaults)
145
//   3. A plist flag for enabling/disabling (overrideable)
146
//   4. The global data collection switch from Core.
147
- (BOOL)isDataCollectionEnabled {
148
  /**
149
   * Perf only works with the default app, so validate it exists then use the value from the global
150
   * data collection from the default app as the base value if no other values are set.
151
   */
152
  if (![self.FIRAppClass isDefaultAppConfigured]) {
153
    return NO;
154
  }
155
 
156
  BOOL dataCollectionPreference = [self.FIRAppClass defaultApp].isDataCollectionDefaultEnabled;
157
 
158
  // Check if data collection is permanently disabled by plist. If so, disable data collection.
159
  id dataCollectionDeactivationObject =
160
      [self objectForInfoDictionaryKey:kFPRConfigCollectionDeactivationPlistKey];
161
  if (dataCollectionDeactivationObject) {
162
    BOOL dataCollectionDeactivated = [dataCollectionDeactivationObject boolValue];
163
    if (dataCollectionDeactivated) {
164
      return NO;
165
    }
166
  }
167
  /**
168
   * Check if the performance collection preference key is available in NSUserDefaults.
169
   * If it exists - Just honor that and return that value.
170
   * If it does not exist - Check if firebase_performance_collection_enabled exists in Info.plist.
171
   * If it exists - honor that and return that value.
172
   * If not - return YES stating performance collection is enabled.
173
   */
174
  id dataCollectionPreferenceObject =
175
      [self.userDefaults objectForKey:kFPRConfigCollectionUserPreference];
176
  if (dataCollectionPreferenceObject) {
177
    dataCollectionPreference = [dataCollectionPreferenceObject boolValue];
178
  } else {
179
    dataCollectionPreferenceObject = [self objectForInfoDictionaryKey:kFPRConfigCollectionPlistKey];
180
    if (dataCollectionPreferenceObject) {
181
      dataCollectionPreference = [dataCollectionPreferenceObject boolValue];
182
    }
183
  }
184
 
185
  return dataCollectionPreference;
186
}
187
 
188
- (void)setInstrumentationEnabled:(BOOL)instrumentationEnabled {
189
  [self.userDefaults setBool:instrumentationEnabled forKey:kFPRConfigInstrumentationUserPreference];
190
}
191
 
192
- (BOOL)isInstrumentationEnabled {
193
  BOOL instrumentationPreference = YES;
194
 
195
  id instrumentationPreferenceObject =
196
      [self.userDefaults objectForKey:kFPRConfigInstrumentationUserPreference];
197
 
198
  /**
199
   * Check if the performance instrumentation preference key is available in NSUserDefaults.
200
   * If it exists - Just honor that and return that value.
201
   * If not - Check if firebase_performance_instrumentation_enabled exists in Info.plist.
202
   * If it exists - honor that and return that value.
203
   * If not - return YES stating performance instrumentation is enabled.
204
   */
205
  if (instrumentationPreferenceObject) {
206
    instrumentationPreference = [instrumentationPreferenceObject boolValue];
207
  } else {
208
    instrumentationPreferenceObject =
209
        [self objectForInfoDictionaryKey:kFPRConfigInstrumentationPlistKey];
210
    if (instrumentationPreferenceObject) {
211
      instrumentationPreference = [instrumentationPreferenceObject boolValue];
212
    }
213
  }
214
 
215
  return instrumentationPreference;
216
}
217
 
218
#pragma mark - Fireperf SDK configurations.
219
 
220
- (BOOL)sdkEnabled {
221
  BOOL enabled = YES;
222
  if (self.remoteConfigFlags) {
223
    enabled = [self.remoteConfigFlags performanceSDKEnabledWithDefaultValue:enabled];
224
  }
225
 
226
  // Check if the current version is one of the disabled versions.
227
  if ([[self sdkDisabledVersions] containsObject:[NSString stringWithUTF8String:kFPRSDKVersion]]) {
228
    enabled = NO;
229
  }
230
 
231
  // If there is a plist override, honor that value.
232
  // NOTE: PList override should ideally be used only for tests and not for production.
233
  id plistObject = [self objectForInfoDictionaryKey:@"firebase_performance_sdk_enabled"];
234
  if (plistObject) {
235
    enabled = [plistObject boolValue];
236
  }
237
 
238
  return enabled;
239
}
240
 
241
- (BOOL)diagnosticsEnabled {
242
  BOOL enabled = NO;
243
 
244
  /**
245
   * Check if the diagnostics preference key is available in NSUserDefaults.
246
   * If it exists - Just honor that and return that value.
247
   * If not - Check if firebase_performance_instrumentation_enabled exists in Info.plist.
248
   * If it exists - honor that and return that value.
249
   * If not - return NO stating diagnostics is disabled.
250
   */
251
  id diagnosticsEnabledPreferenceObject =
252
      [self.userDefaults objectForKey:kFPRDiagnosticsUserPreference];
253
 
254
  if (diagnosticsEnabledPreferenceObject) {
255
    enabled = [diagnosticsEnabledPreferenceObject boolValue];
256
  } else {
257
    id diagnosticsEnabledObject = [self objectForInfoDictionaryKey:kFPRDiagnosticsEnabledPlistKey];
258
    if (diagnosticsEnabledObject) {
259
      enabled = [diagnosticsEnabledObject boolValue];
260
    }
261
  }
262
 
263
  return enabled;
264
}
265
 
266
- (NSSet<NSString *> *)sdkDisabledVersions {
267
  NSMutableSet<NSString *> *disabledVersions = [[NSMutableSet<NSString *> alloc] init];
268
 
269
  if (self.remoteConfigFlags) {
270
    NSSet<NSString *> *sdkDisabledVersions =
271
        [self.remoteConfigFlags sdkDisabledVersionsWithDefaultValue:[disabledVersions copy]];
272
    if (sdkDisabledVersions.count > 0) {
273
      [disabledVersions addObjectsFromArray:[sdkDisabledVersions allObjects]];
274
    }
275
  }
276
 
277
  return [disabledVersions copy];
278
}
279
 
280
- (int)logSource {
281
  /**
282
   * Order of preference of returning the log source.
283
   * If it is an autopush build (based on environment variable), always return
284
   * LogRequest_LogSource_FireperfAutopush (461). If there is a recent value of remote config fetch,
285
   * honor that value. If logSource cached value (NSUserDefaults value) exists, honor that. Fallback
286
   * to the default value LogRequest_LogSource_Fireperf (462).
287
   */
288
  int logSource = 462;
289
 
290
  NSDictionary<NSString *, NSString *> *environment = [NSProcessInfo processInfo].environment;
291
  if (environment[@"FPR_AUTOPUSH_ENV"] != nil &&
292
      [environment[@"FPR_AUTOPUSH_ENV"] isEqualToString:@"1"]) {
293
    logSource = 461;
294
  } else {
295
    if (self.remoteConfigFlags) {
296
      logSource = [self.remoteConfigFlags logSourceWithDefaultValue:462];
297
    }
298
  }
299
 
300
  return logSource;
301
}
302
 
303
- (PrewarmDetectionMode)prewarmDetectionMode {
304
  PrewarmDetectionMode mode = PrewarmDetectionModeActivePrewarm;
305
  if (self.remoteConfigFlags) {
306
    mode = [self.remoteConfigFlags getIntValueForFlag:@"fpr_prewarm_detection"
307
                                         defaultValue:(int)mode];
308
  }
309
  return mode;
310
}
311
 
312
#pragma mark - Log sampling configurations.
313
 
314
- (float)logTraceSamplingRate {
315
  float samplingRate = 1.0f;
316
  if (self.remoteConfigFlags) {
317
    float rcSamplingRate = [self.remoteConfigFlags traceSamplingRateWithDefaultValue:samplingRate];
318
    if (rcSamplingRate >= 0) {
319
      samplingRate = rcSamplingRate;
320
    }
321
  }
322
  return samplingRate;
323
}
324
 
325
- (float)logNetworkSamplingRate {
326
  float samplingRate = 1.0f;
327
  if (self.remoteConfigFlags) {
328
    float rcSamplingRate =
329
        [self.remoteConfigFlags networkRequestSamplingRateWithDefaultValue:samplingRate];
330
    if (rcSamplingRate >= 0) {
331
      samplingRate = rcSamplingRate;
332
    }
333
  }
334
  return samplingRate;
335
}
336
 
337
#pragma mark - Traces rate limiting configurations.
338
 
339
- (uint32_t)foregroundEventCount {
340
  uint32_t eventCount = 300;
341
  if (self.remoteConfigFlags) {
342
    eventCount =
343
        [self.remoteConfigFlags rateLimitTraceCountInForegroundWithDefaultValue:eventCount];
344
  }
345
  return eventCount;
346
}
347
 
348
- (uint32_t)foregroundEventTimeLimit {
349
  uint32_t timeLimit = 600;
350
  if (self.remoteConfigFlags) {
351
    timeLimit = [self.remoteConfigFlags rateLimitTimeDurationWithDefaultValue:timeLimit];
352
  }
353
 
354
  uint32_t timeLimitInMinutes = timeLimit / 60;
355
  return timeLimitInMinutes;
356
}
357
 
358
- (uint32_t)backgroundEventCount {
359
  uint32_t eventCount = 30;
360
  if (self.remoteConfigFlags) {
361
    eventCount =
362
        [self.remoteConfigFlags rateLimitTraceCountInBackgroundWithDefaultValue:eventCount];
363
  }
364
  return eventCount;
365
}
366
 
367
- (uint32_t)backgroundEventTimeLimit {
368
  uint32_t timeLimit = 600;
369
  if (self.remoteConfigFlags) {
370
    timeLimit = [self.remoteConfigFlags rateLimitTimeDurationWithDefaultValue:timeLimit];
371
  }
372
 
373
  uint32_t timeLimitInMinutes = timeLimit / 60;
374
  return timeLimitInMinutes;
375
}
376
 
377
#pragma mark - Network requests rate limiting configurations.
378
 
379
- (uint32_t)foregroundNetworkEventCount {
380
  uint32_t eventCount = 700;
381
  if (self.remoteConfigFlags) {
382
    eventCount = [self.remoteConfigFlags
383
        rateLimitNetworkRequestCountInForegroundWithDefaultValue:eventCount];
384
  }
385
  return eventCount;
386
}
387
 
388
- (uint32_t)foregroundNetworkEventTimeLimit {
389
  uint32_t timeLimit = 600;
390
  if (self.remoteConfigFlags) {
391
    timeLimit = [self.remoteConfigFlags rateLimitTimeDurationWithDefaultValue:timeLimit];
392
  }
393
 
394
  uint32_t timeLimitInMinutes = timeLimit / 60;
395
  return timeLimitInMinutes;
396
}
397
 
398
- (uint32_t)backgroundNetworkEventCount {
399
  uint32_t eventCount = 70;
400
  if (self.remoteConfigFlags) {
401
    eventCount = [self.remoteConfigFlags
402
        rateLimitNetworkRequestCountInBackgroundWithDefaultValue:eventCount];
403
  }
404
  return eventCount;
405
}
406
 
407
- (uint32_t)backgroundNetworkEventTimeLimit {
408
  uint32_t timeLimit = 600;
409
  if (self.remoteConfigFlags) {
410
    timeLimit = [self.remoteConfigFlags rateLimitTimeDurationWithDefaultValue:timeLimit];
411
  }
412
 
413
  uint32_t timeLimitInMinutes = timeLimit / 60;
414
  return timeLimitInMinutes;
415
}
416
 
417
#pragma mark - Sessions feature related configurations.
418
 
419
- (float_t)sessionsSamplingPercentage {
420
  float samplingPercentage = 1.0f;  // One Percent.
421
  if (self.remoteConfigFlags) {
422
    float rcSamplingRate =
423
        [self.remoteConfigFlags sessionSamplingRateWithDefaultValue:(samplingPercentage / 100)];
424
    if (rcSamplingRate >= 0) {
425
      samplingPercentage = rcSamplingRate * 100;
426
    }
427
  }
428
 
429
  id plistObject = [self objectForInfoDictionaryKey:@"sessionsSamplingPercentage"];
430
  if (plistObject) {
431
    samplingPercentage = [plistObject floatValue];
432
  }
433
  return samplingPercentage;
434
}
435
 
436
- (uint32_t)maxSessionLengthInMinutes {
437
  uint32_t sessionLengthInMinutes = 240;
438
  if (self.remoteConfigFlags) {
439
    sessionLengthInMinutes =
440
        [self.remoteConfigFlags sessionMaxDurationWithDefaultValue:sessionLengthInMinutes];
441
  }
442
 
443
  // If the session max length gets set to 0, default it to 240 minutes.
444
  if (sessionLengthInMinutes == 0) {
445
    return 240;
446
  }
447
  return sessionLengthInMinutes;
448
}
449
 
450
- (uint32_t)cpuSamplingFrequencyInForegroundInMS {
451
  uint32_t samplingFrequency = 100;
452
  if (self.remoteConfigFlags) {
453
    samplingFrequency = [self.remoteConfigFlags
454
        sessionGaugeCPUCaptureFrequencyInForegroundWithDefaultValue:samplingFrequency];
455
  }
456
  return samplingFrequency;
457
}
458
 
459
- (uint32_t)cpuSamplingFrequencyInBackgroundInMS {
460
  uint32_t samplingFrequency = 0;
461
  if (self.remoteConfigFlags) {
462
    samplingFrequency = [self.remoteConfigFlags
463
        sessionGaugeCPUCaptureFrequencyInBackgroundWithDefaultValue:samplingFrequency];
464
  }
465
  return samplingFrequency;
466
}
467
 
468
- (uint32_t)memorySamplingFrequencyInForegroundInMS {
469
  uint32_t samplingFrequency = 100;
470
  if (self.remoteConfigFlags) {
471
    samplingFrequency = [self.remoteConfigFlags
472
        sessionGaugeMemoryCaptureFrequencyInForegroundWithDefaultValue:samplingFrequency];
473
  }
474
  return samplingFrequency;
475
}
476
 
477
- (uint32_t)memorySamplingFrequencyInBackgroundInMS {
478
  uint32_t samplingFrequency = 0;
479
  if (self.remoteConfigFlags) {
480
    samplingFrequency = [self.remoteConfigFlags
481
        sessionGaugeMemoryCaptureFrequencyInBackgroundWithDefaultValue:samplingFrequency];
482
  }
483
  return samplingFrequency;
484
}
485
 
486
@end