Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make locationManager initialization thread safe #317

Merged
merged 3 commits into from
Sep 29, 2021
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
26 changes: 15 additions & 11 deletions Sources/MapboxMobileEvents/MMELocationManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@interface MMELocationManager () <CLLocationManagerDelegate>

@property (nonatomic) id<MMEUIApplicationWrapper> application;
@property (nonatomic) CLLocationManager *locationManager;
@property (nonatomic, readonly) CLLocationManager *locationManager;
@property (nonatomic, getter=isUpdatingLocation, readwrite) BOOL updatingLocation;
@property (nonatomic) NSDate *backgroundLocationServiceTimeoutAllowedDate;
@property (nonatomic) NSTimer *backgroundLocationServiceTimeoutTimer;
Expand All @@ -38,10 +38,12 @@ - (void)dealloc {
}

- (CLLocationManager *)locationManager {
if (_locationManager == nil) {
_locationManager = [[MMEDependencyManager sharedManager] locationManagerInstance];
@synchronized (self) {
if (!_locationManager) {
_locationManager = [[MMEDependencyManager sharedManager] locationManagerInstance];
}
return _locationManager;
}
return _locationManager;
}

- (instancetype)init {
Expand Down Expand Up @@ -111,13 +113,15 @@ - (NSString *)accuracyAuthorizationString {
#endif

- (void)setLocationManager:(CLLocationManager *)locationManager {
if (locationManager == nil) {
_locationManager = locationManager;
} else {
id<CLLocationManagerDelegate> delegate = _locationManager.delegate;
_locationManager.delegate = nil;
_locationManager = locationManager;
_locationManager.delegate = delegate;
@synchronized (self) {
if (locationManager == nil) {
_locationManager = locationManager;
} else {
id<CLLocationManagerDelegate> delegate = _locationManager.delegate;
_locationManager.delegate = nil;
_locationManager = locationManager;
_locationManager.delegate = delegate;
}
}
}

Expand Down
36 changes: 36 additions & 0 deletions Sources/MapboxMobileEvents/MMEMetricsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ - (void)pushEvent:(MMEEvent *)event;

@interface MMEMetricsManager ()

@property (nonatomic, readonly, strong) NSRecursiveLock *lock;
@property (nonatomic) MMEMetrics *metrics;

@end
Expand Down Expand Up @@ -115,23 +116,27 @@ + (BOOL)createFrameworkMetricsEventDir {
- (instancetype)init {
if (self = [super init]) {
[self resetMetrics];
_lock = [[NSRecursiveLock alloc] init];
}
return self;
}

- (void)updateMetricsFromEventQueue:(NSArray *)eventQueue {
if (eventQueue.count > 0) {
[self.lock lock];
self.metrics.eventCountTotal += eventQueue.count;

for (MMEEvent *event in eventQueue) {
NSNumber *eventCount = [self.metrics.eventCountPerType objectForKey:event.name];
eventCount = [NSNumber numberWithInteger:[eventCount integerValue] + 1];
[self.metrics.eventCountPerType setObject:eventCount forKey:event.name];
}
[self.lock unlock];
}
}

- (void)updateMetricsFromEventCount:(NSUInteger)eventCount request:(nullable NSURLRequest *)request error:(nullable NSError *)error {
[self.lock lock];
if (request.HTTPBody) {
[self updateSentBytes:request.HTTPBody.length];
}
Expand Down Expand Up @@ -165,72 +170,100 @@ - (void)updateMetricsFromEventCount:(NSUInteger)eventCount request:(nullable NSU

[self.metrics.failedRequestsDict setObject:failedRequests forKey:MMEEventKeyFailedRequests];
}
[self.lock unlock];
}

- (void)updateEventsFailedCount:(NSUInteger)eventCount {
[self.lock lock];
self.metrics.eventCountFailed += eventCount;
[self.lock unlock];
}

- (void)updateSentBytes:(NSUInteger)bytes {
[self.lock lock];
if ([[MMEReachability reachabilityForLocalWiFi] isReachableViaWiFi]) {
self.metrics.wifiBytesSent += bytes;
} else {
self.metrics.cellBytesSent += bytes;
}
[self.lock unlock];
}

- (void)updateReceivedBytes:(NSUInteger)bytes {
[self.lock lock];
if ([[MMEReachability reachabilityForLocalWiFi] isReachableViaWiFi]) {
self.metrics.wifiBytesReceived += bytes;
} else {
self.metrics.cellBytesReceived += bytes;
}
[self.lock unlock];
}

- (void)incrementAppWakeUpCount {
[self.lock lock];
self.metrics.appWakeups++;
[self.lock unlock];
}

- (void)updateConfigurationJSON:(NSDictionary *)configuration {
if (configuration) {
[self.lock lock];
self.metrics.configResponseDict = configuration;
[self.lock unlock];
}
}

- (void)updateCoordinate:(CLLocationCoordinate2D)coordinate {
[self.lock lock];
if (!self.metrics.deviceLat && !self.metrics.deviceLon) {
self.metrics.deviceLat = round(coordinate.latitude*1000)/1000;
self.metrics.deviceLon = round(coordinate.longitude*1000)/1000;
}
[self.lock unlock];
}

- (void)resetMetrics {
[self.lock lock];
self.metrics = [MMEMetrics new];
[self.lock unlock];
}

- (void)incrementLocationsInForeground {
[self.lock lock];
self.metrics.locationsInForeground++;
[self.lock unlock];
}
- (void)incrementLocationsInBackground {
[self.lock lock];
self.metrics.locationsInBackground++;
[self.lock unlock];
}
- (void)incrementLocationsWithApproximateValues {
[self.lock lock];
self.metrics.locationsWithApproximateValues++;
[self.lock unlock];
}

- (void)incrementLocationsDroppedBecauseOfHAF {
[self.lock lock];
self.metrics.locationsDroppedBecauseOfHAF++;
[self.lock unlock];
}

- (void)incrementLocationsDroppedDueTimeout {
[self.lock lock];
self.metrics.locationsDroppedDueTimeout++;
[self.lock unlock];
}

- (void)incrementLocationsConvertedIntoEvents {
[self.lock lock];
self.metrics.locationsConvertedIntoEvents++;
[self.lock unlock];
}

- (NSDictionary *)attributes {
[self.lock lock];
MMEMutableMapboxEventAttributes *attributes = [MMEMutableMapboxEventAttributes dictionary];
if (self.metrics.recordingStarted) {
attributes[MMEEventDateUTC] = [MMEDate.iso8601DateOnlyFormatter stringFromDate:self.metrics.recordingStarted];
Expand Down Expand Up @@ -269,6 +302,7 @@ - (NSDictionary *)attributes {
attributes[MMEEventSDKIdentifier] = NSUserDefaults.mme_configuration.mme_legacyUserAgentBase;
attributes[MMEEventSDKVersion] = NSUserDefaults.mme_configuration.mme_legacyHostSDKVersion;
attributes[MMEEventKeyUserAgent] = NSUserDefaults.mme_configuration.mme_userAgentString;
[self.lock unlock];

return attributes;
}
Expand All @@ -295,7 +329,9 @@ - (MMEEvent *)loadPendingTelemetryMetricsEvent {
}

- (MMEEvent *)generateTelemetryMetricsEvent {
[self.lock lock];
NSDate *zeroHour = [self.metrics.recordingStarted mme_startOfTomorrow];
[self.lock unlock];
NSString *metricsDate = [MMEDate.iso8601DateFormatter stringFromDate:NSDate.date];
MMEEvent *telemetryMetrics = [MMEEvent telemetryMetricsEventWithDateString:metricsDate attributes:self.attributes];

Expand Down
7 changes: 6 additions & 1 deletion Sources/MapboxMobileEvents/MMEUniqueIdentifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

@interface MMEUniqueIdentifier ()

@property (nonatomic, strong, readonly) NSLock *lock;
@property (nonatomic) NSDate *instanceIDRotationDate;
@property (nonatomic) NSString *instanceID;

Expand All @@ -12,19 +13,23 @@ @implementation MMEUniqueIdentifier
- (instancetype)initWithTimeInterval:(NSTimeInterval)timeInterval {
if (self = [super init]) {
_timeInterval = timeInterval;
_lock = [[NSLock alloc] init];
}
return self;
}

- (NSString *)rollingInstanceIdentifer {
[self.lock lock];
if (self.instanceIDRotationDate && [[NSDate date] timeIntervalSinceDate:self.instanceIDRotationDate] >= 0) {
_instanceID = nil;
}
if (!_instanceID) {
_instanceID = [[NSUUID UUID] UUIDString];
self.instanceIDRotationDate = [[NSDate date] dateByAddingTimeInterval:self.timeInterval];
}
return _instanceID;
NSString *instanceID = _instanceID;
[self.lock unlock];
return instanceID;
}

@end