diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 966a3fd70..9b82f5aa0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: hooks: - id: clang-format files: '.*\.(hpp|cpp|h)' - exclude: '(vendor/.*|darwin/include/mbgl/storage/reachability.h)' + exclude: 'vendor/.*' - repo: https://github.com/keith/pre-commit-buildifier rev: 7.3.1 hooks: diff --git a/platform/darwin/BUILD.bazel b/platform/darwin/BUILD.bazel index d9e86bb5e..9c59e9f55 100644 --- a/platform/darwin/BUILD.bazel +++ b/platform/darwin/BUILD.bazel @@ -204,7 +204,6 @@ objc_library( ], hdrs = [ "include/mbgl/interface/native_apple_interface.h", - "include/mbgl/storage/reachability.h", "include/mbgl/util/image+MLNAdditions.hpp", ], copts = WARNING_FLAGS["ios"] + MAPLIBRE_FLAGS + [ @@ -243,7 +242,6 @@ objc_library( }), hdrs = [ "include/mbgl/interface/native_apple_interface.h", - "include/mbgl/storage/reachability.h", "include/mbgl/util/image+MLNAdditions.hpp", ], copts = CPP_FLAGS + MAPLIBRE_FLAGS + [ diff --git a/platform/darwin/include/mbgl/storage/reachability.h b/platform/darwin/include/mbgl/storage/reachability.h deleted file mode 100644 index bfcf78059..000000000 --- a/platform/darwin/include/mbgl/storage/reachability.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (c) 2011, Tony Million. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - */ - -#import -#import - - -/** - * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. - * - * @see http://nshipster.com/ns_enum-ns_options/ - **/ -#ifndef NS_ENUM -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#endif - -extern NSString *const kMLNReachabilityChangedNotification; - -typedef NS_ENUM(NSInteger, NetworkStatus) { - // Apple NetworkStatus Compatible Names. - NotReachable = 0, - ReachableViaWiFi = 2, - ReachableViaWWAN = 1 -}; - -@class MLNReachability; - -typedef void (^NetworkReachable)(MLNReachability * reachability); -typedef void (^NetworkUnreachable)(MLNReachability * reachability); - - -@interface MLNReachability : NSObject - -@property (nonatomic, copy) NetworkReachable reachableBlock; -@property (nonatomic, copy) NetworkUnreachable unreachableBlock; - -@property (nonatomic, assign) BOOL reachableOnWWAN; - - -+(instancetype)reachabilityWithHostname:(NSString*)hostname; -// This is identical to the function above, but is here to maintain -// compatibility with Apples original code. (see .m) -+(instancetype)reachabilityWithHostName:(NSString*)hostname; -+(instancetype)reachabilityForInternetConnection; -+(instancetype)reachabilityWithAddress:(void *)hostAddress; -+(instancetype)reachabilityForLocalWiFi; - --(BOOL)startNotifier; --(void)stopNotifier; - --(BOOL)isReachable; --(BOOL)isReachableViaWWAN; --(BOOL)isReachableViaWiFi; - -// WWAN may be available, but not active until a connection has been established. -// WiFi may require a connection for VPN on Demand. --(BOOL)isConnectionRequired; // Identical DDG variant. --(BOOL)connectionRequired; // Apple's routine. -// Dynamic, on demand connection? --(BOOL)isConnectionOnDemand; -// Is user intervention required? --(BOOL)isInterventionRequired; - --(NetworkStatus)currentReachabilityStatus; --(SCNetworkReachabilityFlags)reachabilityFlags; --(NSString*)currentReachabilityString; --(NSString*)currentReachabilityFlags; - -@end diff --git a/platform/darwin/src/reachability.m b/platform/darwin/src/reachability.m deleted file mode 100644 index 08a4111d8..000000000 --- a/platform/darwin/src/reachability.m +++ /dev/null @@ -1,473 +0,0 @@ -/* - Copyright (c) 2011, Tony Million. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -#import -#import -#import -#import -#import -#import - - -NSString *const kMLNReachabilityChangedNotification = @"kMLNReachabilityChangedNotification"; - - -@interface MLNReachability () - -@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef; -@property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue; -@property (nonatomic, strong) id reachabilityObject; - --(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags; --(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags; - -@end - - -static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) -{ - return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c", -#if TARGET_OS_IPHONE - (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', -#else - 'X', -#endif - (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', - (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', - (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', - (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', - (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', - (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', - (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', - (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-']; -} - -// Start listening for reachability notifications on the current run loop -static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) -{ -#pragma unused (target) - - MLNReachability *reachability = ((__bridge MLNReachability*)info); - - // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool, - // but what the heck eh? - @autoreleasepool - { - [reachability reachabilityChanged:flags]; - } -} - - -@implementation MLNReachability - -// MARK: - Class Constructor Methods - -+(instancetype)reachabilityWithHostName:(NSString*)hostname -{ - return [MLNReachability reachabilityWithHostname:hostname]; -} - -+(instancetype)reachabilityWithHostname:(NSString*)hostname -{ - SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]); - if (ref) - { - id reachability = [[self alloc] initWithReachabilityRef:ref]; - - CFRelease(ref); - - return reachability; - } - - return nil; -} - -+(instancetype)reachabilityWithAddress:(void *)hostAddress -{ - SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); - if (ref) - { - id reachability = [[self alloc] initWithReachabilityRef:ref]; - - CFRelease(ref); - - return reachability; - } - - return nil; -} - -+(instancetype)reachabilityForInternetConnection -{ - struct sockaddr_in zeroAddress; - bzero(&zeroAddress, sizeof(zeroAddress)); - zeroAddress.sin_len = sizeof(zeroAddress); - zeroAddress.sin_family = AF_INET; - - return [self reachabilityWithAddress:&zeroAddress]; -} - -+(instancetype)reachabilityForLocalWiFi -{ - struct sockaddr_in localWifiAddress; - bzero(&localWifiAddress, sizeof(localWifiAddress)); - localWifiAddress.sin_len = sizeof(localWifiAddress); - localWifiAddress.sin_family = AF_INET; - // IN_LINKLOCALNETNUM is defined in as 169.254.0.0 - localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); - - return [self reachabilityWithAddress:&localWifiAddress]; -} - - -// Initialization methods - --(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref -{ - self = [super init]; - if (self != nil) - { - _reachableOnWWAN = YES; - _reachabilityRef = CFRetain(ref); - - // We need to create a serial queue. - // We allocate this once for the lifetime of the notifier. - - _reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL); - } - - return self; -} - --(void)dealloc -{ - [self stopNotifier]; - - if(_reachabilityRef) - { - CFRelease(_reachabilityRef); - _reachabilityRef = nil; - } - - _reachableBlock = nil; - _unreachableBlock = nil; - _reachabilitySerialQueue = nil; -} - -// MARK: - Notifier Methods - -// Notifier -// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD -// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS. -// INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want) - --(BOOL)startNotifier -{ - // allow start notifier to be called multiple times - if(self.reachabilityObject && (self.reachabilityObject == self)) - { - return YES; - } - - - SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL }; - context.info = (__bridge void *)self; - - if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context)) - { - // Set it as our reachability queue, which will retain the queue - if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue)) - { - // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves - // woah - self.reachabilityObject = self; - return YES; - } - else - { -#ifdef DEBUG - NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError())); -#endif - - // UH OH - FAILURE - stop any callbacks! - SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); - } - } - else - { -#ifdef DEBUG - NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError())); -#endif - } - - // if we get here we fail at the internet - self.reachabilityObject = nil; - return NO; -} - --(void)stopNotifier -{ - // First stop, any callbacks! - SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); - - // Unregister target from the GCD serial dispatch queue. - SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL); - - self.reachabilityObject = nil; -} - -// MARK: - reachability tests - -// This is for the case where you flick the airplane mode; -// you end up getting something like this: -// Reachability: WR ct----- -// Reachability: -- ------- -// Reachability: WR ct----- -// Reachability: -- ------- -// We treat this as 4 UNREACHABLE triggers - really apple should do better than this - -#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) - --(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags -{ - BOOL connectionUP = YES; - - if(!(flags & kSCNetworkReachabilityFlagsReachable)) - connectionUP = NO; - - if( (flags & testcase) == testcase ) - connectionUP = NO; - -#if TARGET_OS_IPHONE - if(flags & kSCNetworkReachabilityFlagsIsWWAN) - { - // We're on 3G. - if(!self.reachableOnWWAN) - { - // We don't want to connect when on 3G. - connectionUP = NO; - } - } -#endif - - return connectionUP; -} - --(BOOL)isReachable -{ - SCNetworkReachabilityFlags flags; - - if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - return NO; - - return [self isReachableWithFlags:flags]; -} - --(BOOL)isReachableViaWWAN -{ -#if TARGET_OS_IPHONE - - SCNetworkReachabilityFlags flags = 0; - - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - // Check we're REACHABLE - if(flags & kSCNetworkReachabilityFlagsReachable) - { - // Now, check we're on WWAN - if(flags & kSCNetworkReachabilityFlagsIsWWAN) - { - return YES; - } - } - } -#endif - - return NO; -} - --(BOOL)isReachableViaWiFi -{ - SCNetworkReachabilityFlags flags = 0; - - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - // Check we're reachable - if((flags & kSCNetworkReachabilityFlagsReachable)) - { -#if TARGET_OS_IPHONE - // Check we're NOT on WWAN - if((flags & kSCNetworkReachabilityFlagsIsWWAN)) - { - return NO; - } -#endif - return YES; - } - } - - return NO; -} - - -// WWAN may be available, but not active until a connection has been established. -// WiFi may require a connection for VPN on Demand. --(BOOL)isConnectionRequired -{ - return [self connectionRequired]; -} - --(BOOL)connectionRequired -{ - SCNetworkReachabilityFlags flags; - - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - return (flags & kSCNetworkReachabilityFlagsConnectionRequired); - } - - return NO; -} - -// Dynamic, on demand connection? --(BOOL)isConnectionOnDemand -{ - SCNetworkReachabilityFlags flags; - - if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && - (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand))); - } - - return NO; -} - -// Is user intervention required? --(BOOL)isInterventionRequired -{ - SCNetworkReachabilityFlags flags; - - if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && - (flags & kSCNetworkReachabilityFlagsInterventionRequired)); - } - - return NO; -} - - -// MARK: - reachability status stuff - --(NetworkStatus)currentReachabilityStatus -{ - if([self isReachable]) - { - if([self isReachableViaWiFi]) - return ReachableViaWiFi; - -#if TARGET_OS_IPHONE - return ReachableViaWWAN; -#endif - } - - return NotReachable; -} - --(SCNetworkReachabilityFlags)reachabilityFlags -{ - SCNetworkReachabilityFlags flags = 0; - - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - return flags; - } - - return 0; -} - --(NSString*)currentReachabilityString -{ - NetworkStatus temp = [self currentReachabilityStatus]; - - if(temp == ReachableViaWWAN) - { - // Updated for the fact that we have CDMA phones now! - return NSLocalizedString(@"Cellular", @""); - } - if (temp == ReachableViaWiFi) - { - return NSLocalizedString(@"WiFi", @""); - } - - return NSLocalizedString(@"No Connection", @""); -} - --(NSString*)currentReachabilityFlags -{ - return reachabilityFlags([self reachabilityFlags]); -} - -// MARK: - Callback function calls this method - --(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags -{ - if([self isReachableWithFlags:flags]) - { - if(self.reachableBlock) - { - self.reachableBlock(self); - } - } - else - { - if(self.unreachableBlock) - { - self.unreachableBlock(self); - } - } - - // this makes sure the change notification happens on the MAIN THREAD - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:kMLNReachabilityChangedNotification - object:self]; - }); -} - -// MARK: - Debug Description - -- (NSString *) description -{ - NSString *description = [NSString stringWithFormat:@"<%@: %#x (%@)>", - NSStringFromClass([self class]), (unsigned int) self, [self currentReachabilityFlags]]; - return description; -} - -@end