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 "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
16
#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager+Private.h"
17
 
18
#import "FirebasePerformance/Sources/Common/FPRDiagnostics.h"
19
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
20
#import "FirebasePerformance/Sources/FPRClient.h"
21
#import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeCollector.h"
22
#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeCollector.h"
23
 
24
#import <UIKit/UIKit.h>
25
 
26
// Number of gauge data information after which that gets flushed to Google Data Transport.
27
NSInteger const kGaugeDataBatchSize = 25;
28
 
29
NS_EXTENSION_UNAVAILABLE("Firebase Performance is not supported for extensions.")
30
@interface FPRGaugeManager () <FPRCPUGaugeCollectorDelegate, FPRMemoryGaugeCollectorDelegate>
31
 
32
/** @brief List of gauges that are currently being actively captured. */
33
@property(nonatomic, readwrite) FPRGauges activeGauges;
34
 
35
/** @brief List of gauge information collected. Intentionally this is not a typed collection. Gauge
36
 * data could be CPU Gauge data or Memory gauge data.
37
 */
38
@property(nonatomic) NSMutableArray *gaugeData;
39
 
40
/** @brief Currently active sessionID. */
41
@property(nonatomic, readwrite, copy) NSString *currentSessionId;
42
 
43
@end
44
 
45
@implementation FPRGaugeManager
46
 
47
+ (instancetype)sharedInstance {
48
  static FPRGaugeManager *instance = nil;
49
  static dispatch_once_t onceToken;
50
  dispatch_once(&onceToken, ^{
51
    instance = [[FPRGaugeManager alloc] initWithGauges:FPRGaugeNone];
52
  });
53
  return instance;
54
}
55
 
56
- (instancetype)initWithGauges:(FPRGauges)gauges {
57
  self = [super init];
58
  if (self) {
59
    _activeGauges = FPRGaugeNone;
60
    _gaugeData = [[NSMutableArray alloc] init];
61
    _gaugeDataProtectionQueue =
62
        dispatch_queue_create("com.google.perf.gaugeManager.gaugeData", DISPATCH_QUEUE_SERIAL);
63
    _isColdStart = YES;
64
    [self startAppActivityTracking];
65
  }
66
  return self;
67
}
68
 
69
- (void)dealloc {
70
  [[NSNotificationCenter defaultCenter] removeObserver:self
71
                                                  name:UIApplicationDidBecomeActiveNotification
72
                                                object:[UIApplication sharedApplication]];
73
 
74
  [[NSNotificationCenter defaultCenter] removeObserver:self
75
                                                  name:UIApplicationWillResignActiveNotification
76
                                                object:[UIApplication sharedApplication]];
77
}
78
 
79
/**
80
 * Starts tracking the application state changes.
81
 */
82
- (void)startAppActivityTracking {
83
  [[NSNotificationCenter defaultCenter] addObserver:self
84
                                           selector:@selector(appStateChanged:)
85
                                               name:UIApplicationDidBecomeActiveNotification
86
                                             object:[UIApplication sharedApplication]];
87
 
88
  [[NSNotificationCenter defaultCenter] addObserver:self
89
                                           selector:@selector(appStateChanged:)
90
                                               name:UIApplicationWillResignActiveNotification
91
                                             object:[UIApplication sharedApplication]];
92
}
93
 
94
- (void)appStateChanged:(NSNotification *)notification {
95
  FPRApplicationState applicationState = [FPRAppActivityTracker sharedInstance].applicationState;
96
  [self.cpuGaugeCollector updateSamplingFrequencyForApplicationState:applicationState];
97
  [self.memoryGaugeCollector updateSamplingFrequencyForApplicationState:applicationState];
98
  self.isColdStart = NO;
99
}
100
 
101
#pragma mark - Implementation methods
102
 
103
- (BOOL)gaugeCollectionEnabled {
104
  // Allow gauge collection to happen during cold start. During dispatch time, we do another check
105
  // to make sure if gauge collection is enabled. This is to accomodate gauge metric collection
106
  // during app_start scenario.
107
  if (self.isColdStart) {
108
    return YES;
109
  }
110
 
111
  // Check if the SDK is enabled to collect gauge data.
112
  BOOL sdkEnabled = [[FPRConfigurations sharedInstance] sdkEnabled];
113
  if (!sdkEnabled) {
114
    return NO;
115
  }
116
 
117
  return [FPRConfigurations sharedInstance].isDataCollectionEnabled;
118
}
119
 
120
- (void)startCollectingGauges:(FPRGauges)gauges forSessionId:(NSString *)sessionId {
121
  // Dispatch the already available gauge data with old sessionId.
122
  [self prepareAndDispatchCollectedGaugeDataWithSessionId:self.currentSessionId];
123
 
124
  self.currentSessionId = sessionId;
125
  if (self.gaugeCollectionEnabled) {
126
    if ((gauges & FPRGaugeCPU) == FPRGaugeCPU) {
127
      self.cpuGaugeCollector = [[FPRCPUGaugeCollector alloc] initWithDelegate:self];
128
    }
129
    if ((gauges & FPRGaugeMemory) == FPRGaugeMemory) {
130
      self.memoryGaugeCollector = [[FPRMemoryGaugeCollector alloc] initWithDelegate:self];
131
    }
132
 
133
    self.activeGauges = self.activeGauges | gauges;
134
  }
135
}
136
 
137
- (void)stopCollectingGauges:(FPRGauges)gauges {
138
  if ((gauges & FPRGaugeCPU) == FPRGaugeCPU) {
139
    self.cpuGaugeCollector = nil;
140
  }
141
 
142
  if ((gauges & FPRGaugeMemory) == FPRGaugeMemory) {
143
    self.memoryGaugeCollector = nil;
144
  }
145
 
146
  self.activeGauges = self.activeGauges & ~(gauges);
147
 
148
  // Flush out all the already collected gauge metrics
149
  [self prepareAndDispatchCollectedGaugeDataWithSessionId:self.currentSessionId];
150
}
151
 
152
- (void)collectAllGauges {
153
  if (self.cpuGaugeCollector) {
154
    [self.cpuGaugeCollector collectMetric];
155
  }
156
 
157
  if (self.memoryGaugeCollector) {
158
    [self.memoryGaugeCollector collectMetric];
159
  }
160
}
161
 
162
- (void)dispatchMetric:(id)gaugeMetric {
163
  // If the gauge metric is of type CPU, then dispatch only if CPU collection is enabled.
164
  if ([gaugeMetric isKindOfClass:[FPRCPUGaugeData class]] &&
165
      ((self.activeGauges & FPRGaugeCPU) == FPRGaugeCPU)) {
166
    [self addGaugeData:gaugeMetric];
167
  }
168
 
169
  // If the gauge metric is of type memory, then dispatch only if memory collection is enabled.
170
  if ([gaugeMetric isKindOfClass:[FPRMemoryGaugeData class]] &&
171
      ((self.activeGauges & FPRGaugeMemory) == FPRGaugeMemory)) {
172
    [self addGaugeData:gaugeMetric];
173
  }
174
}
175
 
176
#pragma mark - Utils
177
 
178
- (void)prepareAndDispatchCollectedGaugeDataWithSessionId:(nullable NSString *)sessionId {
179
  dispatch_async(self.gaugeDataProtectionQueue, ^{
180
    NSArray *dispatchGauges = [self.gaugeData copy];
181
    self.gaugeData = [[NSMutableArray alloc] init];
182
 
183
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
184
      if (dispatchGauges.count > 0 && sessionId != nil) {
185
        [[FPRClient sharedInstance] logGaugeMetric:dispatchGauges forSessionId:sessionId];
186
        FPRLogInfo(kFPRGaugeManagerDataCollected, @"Logging %lu gauge metrics.",
187
                   (unsigned long)dispatchGauges.count);
188
      }
189
    });
190
  });
191
}
192
 
193
/**
194
 * Adds the gauge to the batch and decide on when to dispatch the events to Google Data Transport.
195
 *
196
 * @param gauge Gauge data received from the collectors.
197
 */
198
- (void)addGaugeData:(id)gauge {
199
  dispatch_async(self.gaugeDataProtectionQueue, ^{
200
    if (gauge) {
201
      [self.gaugeData addObject:gauge];
202
 
203
      if (self.gaugeData.count >= kGaugeDataBatchSize) {
204
        [self prepareAndDispatchCollectedGaugeDataWithSessionId:self.currentSessionId];
205
      }
206
    }
207
  });
208
}
209
 
210
#pragma mark - FPRCPUGaugeCollectorDelegate methods
211
 
212
- (void)cpuGaugeCollector:(FPRCPUGaugeCollector *)collector gaugeData:(FPRCPUGaugeData *)gaugeData {
213
  [self addGaugeData:gaugeData];
214
}
215
 
216
#pragma mark - FPRMemoryGaugeCollectorDelegate methods
217
 
218
- (void)memoryGaugeCollector:(FPRMemoryGaugeCollector *)collector
219
                   gaugeData:(FPRMemoryGaugeData *)gaugeData {
220
  [self addGaugeData:gaugeData];
221
}
222
 
223
@end