From e2e598bd11ae2eabb039fc0f9a318304dd631274 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 26 Jul 2022 10:38:27 -0700 Subject: [PATCH 1/3] Remove availability and fallbacks for iOS 11 and macOS 10.13 --- .../renderer/backend/metal/allocator_mtl.mm | 12 +- .../backend/metal/command_buffer_mtl.mm | 29 --- .../backend/metal/device_buffer_mtl.mm | 10 +- .../backend/metal/vertex_descriptor_mtl.mm | 36 +-- .../ios/framework/Headers/FlutterPlugin.h | 11 +- .../FlutterPluginAppLifeCycleDelegate.h | 5 +- .../framework/Source/FlutterAppDelegate.mm | 33 +-- .../Source/FlutterObservatoryPublisher.mm | 53 +--- .../framework/Source/FlutterPlatformPlugin.mm | 34 +-- .../FlutterPluginAppLifeCycleDelegate.mm | 31 +-- .../Source/FlutterTextInputPlugin.mm | 242 ++++++++---------- .../framework/Source/FlutterViewController.mm | 157 +++++------- .../Source/FlutterViewControllerTest.mm | 14 - .../framework/Source/VsyncWaiterIosTest.mm | 6 +- .../framework/Source/accessibility_bridge.mm | 17 +- .../ios/framework/Source/vsync_waiter_ios.mm | 41 ++- .../platform/darwin/ios/platform_view_ios.mm | 16 +- .../Source/AccessibilityBridgeMacDelegate.mm | 19 +- .../framework/Source/FlutterViewController.mm | 47 ++-- .../Source/FlutterViewControllerTest.mm | 80 +++--- 20 files changed, 323 insertions(+), 570 deletions(-) diff --git a/impeller/renderer/backend/metal/allocator_mtl.mm b/impeller/renderer/backend/metal/allocator_mtl.mm index cd5730e0b0994..7b0120503d630 100644 --- a/impeller/renderer/backend/metal/allocator_mtl.mm +++ b/impeller/renderer/backend/metal/allocator_mtl.mm @@ -41,11 +41,7 @@ static MTLResourceOptions ToMTLResourceOptions(StorageMode type) { return MTLResourceStorageModePrivate; case StorageMode::kDeviceTransient: #if FML_OS_IOS - if (@available(iOS 10.0, *)) { - return MTLResourceStorageModeMemoryless; - } else { - return MTLResourceStorageModePrivate; - } + return MTLResourceStorageModeMemoryless; #else return MTLResourceStorageModePrivate; #endif @@ -66,11 +62,7 @@ static MTLStorageMode ToMTLStorageMode(StorageMode mode) { return MTLStorageModePrivate; case StorageMode::kDeviceTransient: #if FML_OS_IOS - if (@available(iOS 10.0, *)) { - return MTLStorageModeMemoryless; - } else { - return MTLStorageModePrivate; - } + return MTLStorageModeMemoryless; #else return MTLStorageModePrivate; #endif diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.mm b/impeller/renderer/backend/metal/command_buffer_mtl.mm index 5c3e62bf76dc4..dd3901f46addf 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/command_buffer_mtl.mm @@ -9,23 +9,6 @@ namespace impeller { namespace { -// NOLINTBEGIN(readability-identifier-naming) - -// TODO(dnfield): remove this declaration when we no longer need to build on -// machines with lower SDK versions than 11.0. -#if !defined(MAC_OS_VERSION_11_0) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_11_0 -typedef NS_ENUM(NSInteger, MTLCommandEncoderErrorState) { - MTLCommandEncoderErrorStateUnknown = 0, - MTLCommandEncoderErrorStateCompleted = 1, - MTLCommandEncoderErrorStateAffected = 2, - MTLCommandEncoderErrorStatePending = 3, - MTLCommandEncoderErrorStateFaulted = 4, -} API_AVAILABLE(macos(11.0), ios(14.0)); -#endif - -// NOLINTEND(readability-identifier-naming) - API_AVAILABLE(ios(14.0), macos(11.0)) NSString* MTLCommandEncoderErrorStateToString( MTLCommandEncoderErrorState state) { @@ -44,18 +27,6 @@ typedef NS_ENUM(NSInteger, MTLCommandEncoderErrorState) { return @"unknown"; } -// NOLINTBEGIN(readability-identifier-naming) - -// TODO(dnfield): This can be removed when all bots have been sufficiently -// upgraded for MAC_OS_VERSION_12_0. -#if !defined(MAC_OS_VERSION_12_0) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0 -constexpr int MTLCommandBufferErrorAccessRevoked = 4; -constexpr int MTLCommandBufferErrorStackOverflow = 12; -#endif - -// NOLINTEND(readability-identifier-naming) - static NSString* MTLCommandBufferErrorToString(MTLCommandBufferError code) { switch (code) { case MTLCommandBufferErrorNone: diff --git a/impeller/renderer/backend/metal/device_buffer_mtl.mm b/impeller/renderer/backend/metal/device_buffer_mtl.mm index 1b81ae157c457..32e7c551439c9 100644 --- a/impeller/renderer/backend/metal/device_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/device_buffer_mtl.mm @@ -73,13 +73,9 @@ if (label.empty()) { return false; } - if (@available(macOS 10.12, iOS 10.0, *)) { - [buffer_ addDebugMarker:@(label.c_str()) - range:NSMakeRange(range.offset, range.length)]; - return true; - } else { - return SetLabel(label); - } + [buffer_ addDebugMarker:@(label.c_str()) + range:NSMakeRange(range.offset, range.length)]; + return true; FML_UNREACHABLE(); } diff --git a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm index c74ba74a49e48..a49a227324b26 100644 --- a/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm +++ b/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm @@ -39,11 +39,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { if (input.bit_width == 8 * sizeof(float) / 2) { switch (input.vec_size) { case 1: - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatHalf; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatHalf; case 2: return MTLVertexFormatHalf2; case 3: @@ -60,11 +56,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { } case ShaderType::kBoolean: { if (input.bit_width == 8 * sizeof(bool) && input.vec_size == 1) { - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatChar; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatChar; } return MTLVertexFormatInvalid; } @@ -72,11 +64,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { if (input.bit_width == 8 * sizeof(char)) { switch (input.vec_size) { case 1: - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatChar; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatChar; case 2: return MTLVertexFormatChar2; case 3: @@ -91,11 +79,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { if (input.bit_width == 8 * sizeof(char)) { switch (input.vec_size) { case 1: - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatUChar; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatUChar; case 2: return MTLVertexFormatUChar2; case 3: @@ -110,11 +94,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { if (input.bit_width == 8 * sizeof(short)) { switch (input.vec_size) { case 1: - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatShort; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatShort; case 2: return MTLVertexFormatShort2; case 3: @@ -129,11 +109,7 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) { if (input.bit_width == 8 * sizeof(ushort)) { switch (input.vec_size) { case 1: - if (@available(macOS 10.13, iOS 11.0, *)) { - return MTLVertexFormatUShort; - } else { - return MTLVertexFormatInvalid; - } + return MTLVertexFormatUShort; case 2: return MTLVertexFormatUShort2; case 3: diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h b/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h index 8b212c3e4da00..e86ce58344b3d 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h @@ -22,10 +22,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Protocol for listener of events from the UIApplication, typically a FlutterPlugin. */ -@protocol FlutterApplicationLifeCycleDelegate -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -#endif +@protocol FlutterApplicationLifeCycleDelegate + @optional /** * Called if this has been registered for `UIApplicationDelegate` callbacks. @@ -432,10 +430,7 @@ typedef enum { * For plugins to receive events from `UNUserNotificationCenter`, register this as the * `UNUserNotificationCenterDelegate`. */ -@protocol FlutterAppLifeCycleProvider -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -#endif +@protocol FlutterAppLifeCycleProvider /** * Called when registering a new `FlutterApplicaitonLifeCycleDelegate`. diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h b/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h index dd6489c6f6355..883dccb8673f3 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h @@ -13,10 +13,7 @@ NS_ASSUME_NONNULL_BEGIN * Propagates `UIAppDelegate` callbacks to registered plugins. */ FLUTTER_DARWIN_EXPORT -@interface FlutterPluginAppLifeCycleDelegate : NSObject -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -#endif +@interface FlutterPluginAppLifeCycleDelegate : NSObject /** * Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate diff --git a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm index a50924e1661ce..9e0c86f8daddd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm @@ -113,14 +113,11 @@ - (void)application:(UIApplication*)application - (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler: - (void (^)(UNNotificationPresentationOptions options))completionHandler - NS_AVAILABLE_IOS(10_0) { - if (@available(iOS 10.0, *)) { - if ([_lifeCycleDelegate respondsToSelector:_cmd]) { - [_lifeCycleDelegate userNotificationCenter:center - willPresentNotification:notification - withCompletionHandler:completionHandler]; - } + (void (^)(UNNotificationPresentationOptions options))completionHandler { + if ([_lifeCycleDelegate respondsToSelector:_cmd]) { + [_lifeCycleDelegate userNotificationCenter:center + willPresentNotification:notification + withCompletionHandler:completionHandler]; } } @@ -129,13 +126,11 @@ - (void)userNotificationCenter:(UNUserNotificationCenter*)center */ - (void)userNotificationCenter:(UNUserNotificationCenter*)center didReceiveNotificationResponse:(UNNotificationResponse*)response - withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10_0) { - if (@available(iOS 10.0, *)) { - if ([_lifeCycleDelegate respondsToSelector:_cmd]) { - [_lifeCycleDelegate userNotificationCenter:center - didReceiveNotificationResponse:response - withCompletionHandler:completionHandler]; - } + withCompletionHandler:(void (^)(void))completionHandler { + if ([_lifeCycleDelegate respondsToSelector:_cmd]) { + [_lifeCycleDelegate userNotificationCenter:center + didReceiveNotificationResponse:response + withCompletionHandler:completionHandler]; } } @@ -199,7 +194,7 @@ - (BOOL)application:(UIApplication*)application - (void)application:(UIApplication*)application performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem - completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) { + completionHandler:(void (^)(BOOL succeeded))completionHandler { [_lifeCycleDelegate application:application performActionForShortcutItem:shortcutItem completionHandler:completionHandler]; @@ -213,16 +208,10 @@ - (void)application:(UIApplication*)application completionHandler:completionHandler]; } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 - (BOOL)application:(UIApplication*)application continueUserActivity:(NSUserActivity*)userActivity restorationHandler:(void (^)(NSArray>* __nullable restorableObjects))restorationHandler { -#else -- (BOOL)application:(UIApplication*)application - continueUserActivity:(NSUserActivity*)userActivity - restorationHandler:(void (^)(NSArray* __nullable restorableObjects))restorationHandler { -#endif if ([_lifeCycleDelegate application:application continueUserActivity:userActivity restorationHandler:restorationHandler]) { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm b/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm index ccf1bbc70de2d..2e6242270a052 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.mm @@ -60,10 +60,6 @@ + (NSData*)createTxtData:(NSURL*)url; @end -@interface ObservatoryNSNetServiceDelegate - : NSObject -@end - @interface ObservatoryDNSServiceDelegate : NSObject @end @@ -116,15 +112,6 @@ - (void)publishServiceProtocolPort:(NSURL*)url { } } -/// TODO(aaclarke): Remove this preprocessor macro once infra is moved to Xcode 12. -static const DNSServiceErrorType kFlutter_DNSServiceErr_PolicyDenied = -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 - kDNSServiceErr_PolicyDenied; -#else - // Found in usr/include/dns_sd.h. - -65570; -#endif // __IPHONE_OS_VERSION_MAX_ALLOWED - static void DNSSD_API RegistrationCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, @@ -134,7 +121,7 @@ static void DNSSD_API RegistrationCallback(DNSServiceRef sdRef, void* context) { if (errorCode == kDNSServiceErr_NoError) { FML_DLOG(INFO) << "FlutterObservatoryPublisher is ready!"; - } else if (errorCode == kFlutter_DNSServiceErr_PolicyDenied) { + } else if (errorCode == kDNSServiceErr_PolicyDenied) { FML_LOG(ERROR) << "Could not register as server for FlutterObservatoryPublisher, permission " << "denied. Check your 'Local Network' permissions for this app in the Privacy section of " @@ -147,38 +134,6 @@ static void DNSSD_API RegistrationCallback(DNSServiceRef sdRef, @end -@implementation ObservatoryNSNetServiceDelegate { - fml::scoped_nsobject _netService; -} - -- (void)stopService { - [_netService.get() stop]; - [_netService.get() setDelegate:nil]; -} - -- (void)publishServiceProtocolPort:(NSURL*)url { - NSNetService* netServiceTmp = - [[NSNetService alloc] initWithDomain:@"local." - type:@"_dartobservatory._tcp." - name:FlutterObservatoryPublisher.serviceName - port:[[url port] intValue]]; - [netServiceTmp setTXTRecordData:[FlutterObservatoryPublisher createTxtData:url]]; - _netService.reset(netServiceTmp); - [_netService.get() setDelegate:self]; - [_netService.get() publish]; -} - -- (void)netServiceDidPublish:(NSNetService*)sender { - FML_DLOG(INFO) << "FlutterObservatoryPublisher is ready!"; -} - -- (void)netService:(NSNetService*)sender didNotPublish:(NSDictionary*)errorDict { - FML_LOG(ERROR) << "Could not register as server for FlutterObservatoryPublisher. Check your " - "network settings and relaunch the application."; -} - -@end - @implementation FlutterObservatoryPublisher { flutter::DartServiceIsolate::CallbackHandle _callbackHandle; std::unique_ptr> _weakFactory; @@ -188,11 +143,7 @@ - (instancetype)initWithEnableObservatoryPublication:(BOOL)enableObservatoryPubl self = [super init]; NSAssert(self, @"Super must not return null on init."); - if (@available(iOS 9.3, *)) { - _delegate.reset([[ObservatoryDNSServiceDelegate alloc] init]); - } else { - _delegate.reset([[ObservatoryNSNetServiceDelegate alloc] init]); - } + _delegate.reset([[ObservatoryDNSServiceDelegate alloc] init]); _enableObservatoryPublication = enableObservatoryPublication; _weakFactory = std::make_unique>(self); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 23264b5cf61c6..6d9e2d7114c2d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -107,19 +107,17 @@ - (void)vibrateHapticFeedback:(NSString*)feedbackType { return; } - if (@available(iOS 10, *)) { - if ([@"HapticFeedbackType.lightImpact" isEqualToString:feedbackType]) { - [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight] autorelease] - impactOccurred]; - } else if ([@"HapticFeedbackType.mediumImpact" isEqualToString:feedbackType]) { - [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium] autorelease] - impactOccurred]; - } else if ([@"HapticFeedbackType.heavyImpact" isEqualToString:feedbackType]) { - [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleHeavy] autorelease] - impactOccurred]; - } else if ([@"HapticFeedbackType.selectionClick" isEqualToString:feedbackType]) { - [[[[UISelectionFeedbackGenerator alloc] init] autorelease] selectionChanged]; - } + if ([@"HapticFeedbackType.lightImpact" isEqualToString:feedbackType]) { + [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight] autorelease] + impactOccurred]; + } else if ([@"HapticFeedbackType.mediumImpact" isEqualToString:feedbackType]) { + [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium] autorelease] + impactOccurred]; + } else if ([@"HapticFeedbackType.heavyImpact" isEqualToString:feedbackType]) { + [[[[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleHeavy] autorelease] + impactOccurred]; + } else if ([@"HapticFeedbackType.selectionClick" isEqualToString:feedbackType]) { + [[[[UISelectionFeedbackGenerator alloc] init] autorelease] selectionChanged]; } } @@ -276,15 +274,7 @@ - (void)setClipboardData:(NSDictionary*)data { } - (NSDictionary*)clipboardHasStrings { - bool hasStrings = false; - UIPasteboard* pasteboard = [UIPasteboard generalPasteboard]; - if (@available(iOS 10, *)) { - hasStrings = pasteboard.hasStrings; - } else { - NSString* stringInPasteboard = pasteboard.string; - hasStrings = stringInPasteboard != nil; - } - return @{@"value" : @(hasStrings)}; + return @{@"value" : @([UIPasteboard generalPasteboard].hasStrings)}; } @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm b/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm index 66f86c52c3524..d493f30d11feb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm @@ -295,29 +295,24 @@ - (void)application:(UIApplication*)application - (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler: - (void (^)(UNNotificationPresentationOptions options))completionHandler - NS_AVAILABLE_IOS(10_0) { - if (@available(iOS 10.0, *)) { - for (NSObject* delegate in _delegates) { - if ([delegate respondsToSelector:_cmd]) { - [delegate userNotificationCenter:center - willPresentNotification:notification - withCompletionHandler:completionHandler]; - } + (void (^)(UNNotificationPresentationOptions options))completionHandler { + for (NSObject* delegate in _delegates) { + if ([delegate respondsToSelector:_cmd]) { + [delegate userNotificationCenter:center + willPresentNotification:notification + withCompletionHandler:completionHandler]; } } } - (void)userNotificationCenter:(UNUserNotificationCenter*)center didReceiveNotificationResponse:(UNNotificationResponse*)response - withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10_0) { - if (@available(iOS 10.0, *)) { - for (id delegate in _delegates) { - if ([delegate respondsToSelector:_cmd]) { - [delegate userNotificationCenter:center - didReceiveNotificationResponse:response - withCompletionHandler:completionHandler]; - } + withCompletionHandler:(void (^)(void))completionHandler { + for (id delegate in _delegates) { + if ([delegate respondsToSelector:_cmd]) { + [delegate userNotificationCenter:center + didReceiveNotificationResponse:response + withCompletionHandler:completionHandler]; } } } @@ -374,7 +369,7 @@ - (BOOL)application:(UIApplication*)application - (void)application:(UIApplication*)application performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem - completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) { + completionHandler:(void (^)(BOOL succeeded))completionHandler { for (NSObject* delegate in _delegates) { if (!delegate) { continue; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index 2d33fb9d6d22d..779717793c4fb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -160,10 +160,8 @@ static UIReturnKeyType ToUIReturnKeyType(NSString* inputType) { return UIReturnKeyNext; } - if (@available(iOS 9.0, *)) { - if ([inputType isEqualToString:@"TextInputAction.continueAction"]) { - return UIReturnKeyContinue; - } + if ([inputType isEqualToString:@"TextInputAction.continueAction"]) { + return UIReturnKeyContinue; } if ([inputType isEqualToString:@"TextInputAction.join"]) { @@ -193,100 +191,96 @@ static UITextContentType ToUITextContentType(NSArray* hints) { } NSString* hint = hints[0]; - if (@available(iOS 10.0, *)) { - if ([hint isEqualToString:@"addressCityAndState"]) { - return UITextContentTypeAddressCityAndState; - } + if ([hint isEqualToString:@"addressCityAndState"]) { + return UITextContentTypeAddressCityAndState; + } - if ([hint isEqualToString:@"addressState"]) { - return UITextContentTypeAddressState; - } + if ([hint isEqualToString:@"addressState"]) { + return UITextContentTypeAddressState; + } - if ([hint isEqualToString:@"addressCity"]) { - return UITextContentTypeAddressCity; - } + if ([hint isEqualToString:@"addressCity"]) { + return UITextContentTypeAddressCity; + } - if ([hint isEqualToString:@"sublocality"]) { - return UITextContentTypeSublocality; - } + if ([hint isEqualToString:@"sublocality"]) { + return UITextContentTypeSublocality; + } - if ([hint isEqualToString:@"streetAddressLine1"]) { - return UITextContentTypeStreetAddressLine1; - } + if ([hint isEqualToString:@"streetAddressLine1"]) { + return UITextContentTypeStreetAddressLine1; + } - if ([hint isEqualToString:@"streetAddressLine2"]) { - return UITextContentTypeStreetAddressLine2; - } + if ([hint isEqualToString:@"streetAddressLine2"]) { + return UITextContentTypeStreetAddressLine2; + } - if ([hint isEqualToString:@"countryName"]) { - return UITextContentTypeCountryName; - } + if ([hint isEqualToString:@"countryName"]) { + return UITextContentTypeCountryName; + } - if ([hint isEqualToString:@"fullStreetAddress"]) { - return UITextContentTypeFullStreetAddress; - } + if ([hint isEqualToString:@"fullStreetAddress"]) { + return UITextContentTypeFullStreetAddress; + } - if ([hint isEqualToString:@"postalCode"]) { - return UITextContentTypePostalCode; - } + if ([hint isEqualToString:@"postalCode"]) { + return UITextContentTypePostalCode; + } - if ([hint isEqualToString:@"location"]) { - return UITextContentTypeLocation; - } + if ([hint isEqualToString:@"location"]) { + return UITextContentTypeLocation; + } - if ([hint isEqualToString:@"creditCardNumber"]) { - return UITextContentTypeCreditCardNumber; - } + if ([hint isEqualToString:@"creditCardNumber"]) { + return UITextContentTypeCreditCardNumber; + } - if ([hint isEqualToString:@"email"]) { - return UITextContentTypeEmailAddress; - } + if ([hint isEqualToString:@"email"]) { + return UITextContentTypeEmailAddress; + } - if ([hint isEqualToString:@"jobTitle"]) { - return UITextContentTypeJobTitle; - } + if ([hint isEqualToString:@"jobTitle"]) { + return UITextContentTypeJobTitle; + } - if ([hint isEqualToString:@"givenName"]) { - return UITextContentTypeGivenName; - } + if ([hint isEqualToString:@"givenName"]) { + return UITextContentTypeGivenName; + } - if ([hint isEqualToString:@"middleName"]) { - return UITextContentTypeMiddleName; - } + if ([hint isEqualToString:@"middleName"]) { + return UITextContentTypeMiddleName; + } - if ([hint isEqualToString:@"familyName"]) { - return UITextContentTypeFamilyName; - } + if ([hint isEqualToString:@"familyName"]) { + return UITextContentTypeFamilyName; + } - if ([hint isEqualToString:@"name"]) { - return UITextContentTypeName; - } + if ([hint isEqualToString:@"name"]) { + return UITextContentTypeName; + } - if ([hint isEqualToString:@"namePrefix"]) { - return UITextContentTypeNamePrefix; - } + if ([hint isEqualToString:@"namePrefix"]) { + return UITextContentTypeNamePrefix; + } - if ([hint isEqualToString:@"nameSuffix"]) { - return UITextContentTypeNameSuffix; - } + if ([hint isEqualToString:@"nameSuffix"]) { + return UITextContentTypeNameSuffix; + } - if ([hint isEqualToString:@"nickname"]) { - return UITextContentTypeNickname; - } + if ([hint isEqualToString:@"nickname"]) { + return UITextContentTypeNickname; + } - if ([hint isEqualToString:@"organizationName"]) { - return UITextContentTypeOrganizationName; - } + if ([hint isEqualToString:@"organizationName"]) { + return UITextContentTypeOrganizationName; + } - if ([hint isEqualToString:@"telephoneNumber"]) { - return UITextContentTypeTelephoneNumber; - } + if ([hint isEqualToString:@"telephoneNumber"]) { + return UITextContentTypeTelephoneNumber; } - if (@available(iOS 11.0, *)) { - if ([hint isEqualToString:@"password"]) { - return UITextContentTypePassword; - } + if ([hint isEqualToString:@"password"]) { + return UITextContentTypePassword; } if (@available(iOS 12.0, *)) { @@ -374,31 +368,27 @@ typedef NS_ENUM(NSInteger, FlutterAutofillType) { }; static BOOL IsFieldPasswordRelated(NSDictionary* configuration) { - if (@available(iOS 10.0, *)) { - // Autofill is explicitly disabled if the id isn't present. - if (!AutofillIdFromDictionary(configuration)) { - return NO; - } + // Autofill is explicitly disabled if the id isn't present. + if (!AutofillIdFromDictionary(configuration)) { + return NO; + } - BOOL isSecureTextEntry = [configuration[kSecureTextEntry] boolValue]; - if (isSecureTextEntry) { - return YES; - } + BOOL isSecureTextEntry = [configuration[kSecureTextEntry] boolValue]; + if (isSecureTextEntry) { + return YES; + } - NSDictionary* autofill = configuration[kAutofillProperties]; - UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]); + NSDictionary* autofill = configuration[kAutofillProperties]; + UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]); - if (@available(iOS 11.0, *)) { - if ([contentType isEqualToString:UITextContentTypePassword] || - [contentType isEqualToString:UITextContentTypeUsername]) { - return YES; - } - } + if ([contentType isEqualToString:UITextContentTypePassword] || + [contentType isEqualToString:UITextContentTypeUsername]) { + return YES; + } - if (@available(iOS 12.0, *)) { - if ([contentType isEqualToString:UITextContentTypeNewPassword]) { - return YES; - } + if (@available(iOS 12.0, *)) { + if ([contentType isEqualToString:UITextContentTypeNewPassword]) { + return YES; } } return NO; @@ -415,14 +405,10 @@ static FlutterAutofillType AutofillTypeOf(NSDictionary* configuration) { return kFlutterAutofillTypePassword; } - if (@available(iOS 10.0, *)) { - NSDictionary* autofill = configuration[kAutofillProperties]; - UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]); - return !autofill || [contentType isEqualToString:@""] ? kFlutterAutofillTypeNone - : kFlutterAutofillTypeRegular; - } - - return kFlutterAutofillTypeNone; + NSDictionary* autofill = configuration[kAutofillProperties]; + UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]); + return !autofill || [contentType isEqualToString:@""] ? kFlutterAutofillTypeNone + : kFlutterAutofillTypeRegular; } static BOOL IsApproximatelyEqual(float x, float y, float delta) { @@ -774,10 +760,8 @@ - (instancetype)initWithOwner:(FlutterTextInputPlugin*)textInputPlugin { _enableInteractiveSelection = YES; _accessibilityEnabled = NO; _decommissioned = NO; - if (@available(iOS 11.0, *)) { - _smartQuotesType = UITextSmartQuotesTypeYes; - _smartDashesType = UITextSmartDashesTypeYes; - } + _smartQuotesType = UITextSmartQuotesTypeYes; + _smartDashesType = UITextSmartDashesTypeYes; _selectionRects = [[NSArray alloc] init]; if (@available(iOS 14.0, *)) { @@ -804,18 +788,14 @@ - (void)configureWithDictionary:(NSDictionary*)configuration { self.returnKeyType = ToUIReturnKeyType(configuration[kInputAction]); self.autocapitalizationType = ToUITextAutoCapitalizationType(configuration); _enableInteractiveSelection = [configuration[kEnableInteractiveSelection] boolValue]; - if (@available(iOS 11.0, *)) { - NSString* smartDashesType = configuration[kSmartDashesType]; - // This index comes from the SmartDashesType enum in the framework. - bool smartDashesIsDisabled = smartDashesType && [smartDashesType isEqualToString:@"0"]; - self.smartDashesType = - smartDashesIsDisabled ? UITextSmartDashesTypeNo : UITextSmartDashesTypeYes; - NSString* smartQuotesType = configuration[kSmartQuotesType]; - // This index comes from the SmartQuotesType enum in the framework. - bool smartQuotesIsDisabled = smartQuotesType && [smartQuotesType isEqualToString:@"0"]; - self.smartQuotesType = - smartQuotesIsDisabled ? UITextSmartQuotesTypeNo : UITextSmartQuotesTypeYes; - } + NSString* smartDashesType = configuration[kSmartDashesType]; + // This index comes from the SmartDashesType enum in the framework. + bool smartDashesIsDisabled = smartDashesType && [smartDashesType isEqualToString:@"0"]; + self.smartDashesType = smartDashesIsDisabled ? UITextSmartDashesTypeNo : UITextSmartDashesTypeYes; + NSString* smartQuotesType = configuration[kSmartQuotesType]; + // This index comes from the SmartQuotesType enum in the framework. + bool smartQuotesIsDisabled = smartQuotesType && [smartQuotesType isEqualToString:@"0"]; + self.smartQuotesType = smartQuotesIsDisabled ? UITextSmartQuotesTypeNo : UITextSmartQuotesTypeYes; if ([keyboardAppearance isEqualToString:@"Brightness.dark"]) { self.keyboardAppearance = UIKeyboardAppearanceDark; } else if ([keyboardAppearance isEqualToString:@"Brightness.light"]) { @@ -827,19 +807,17 @@ - (void)configureWithDictionary:(NSDictionary*)configuration { self.autocorrectionType = autocorrect && ![autocorrect boolValue] ? UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault; - if (@available(iOS 10.0, *)) { - self.autofillId = AutofillIdFromDictionary(configuration); - if (autofill == nil) { - self.textContentType = @""; - } else { - self.textContentType = ToUITextContentType(autofill[kAutofillHints]); - [self setTextInputState:autofill[kAutofillEditingValue]]; - NSAssert(_autofillId, @"The autofill configuration must contain an autofill id"); - } - // The input field needs to be visible for the system autofill - // to find it. - self.isVisibleToAutofill = autofill || _secureTextEntry; + self.autofillId = AutofillIdFromDictionary(configuration); + if (autofill == nil) { + self.textContentType = @""; + } else { + self.textContentType = ToUITextContentType(autofill[kAutofillHints]); + [self setTextInputState:autofill[kAutofillEditingValue]]; + NSAssert(_autofillId, @"The autofill configuration must contain an autofill id"); } + // The input field needs to be visible for the system autofill + // to find it. + self.isVisibleToAutofill = autofill || _secureTextEntry; } - (UITextContentType)textContentType { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 9834d47fdf362..2d9f8a4ff1945 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -90,20 +90,6 @@ - (void)addInternalPlugins; - (void)deregisterNotifications; @end -// The following conditional compilation defines an API 13 concept on earlier API targets so that -// a compiler compiling against API 12 or below does not blow up due to non-existent members. -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 130000 -typedef enum UIAccessibilityContrast : NSInteger { - UIAccessibilityContrastUnspecified = 0, - UIAccessibilityContrastNormal = 1, - UIAccessibilityContrastHigh = 2 -} UIAccessibilityContrast; - -@interface UITraitCollection (MethodsFromNewerSDK) -- (UIAccessibilityContrast)accessibilityContrast; -@end -#endif - @implementation FlutterViewController { std::unique_ptr> _weakFactory; fml::scoped_nsobject _engine; @@ -924,19 +910,17 @@ - (void)goToApplicationLifecycle:(nonnull NSString*)state { } static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch) { - if (@available(iOS 9, *)) { - switch (touch.type) { - case UITouchTypeDirect: - case UITouchTypeIndirect: - return flutter::PointerData::DeviceKind::kTouch; - case UITouchTypeStylus: - return flutter::PointerData::DeviceKind::kStylus; - case UITouchTypeIndirectPointer: - return flutter::PointerData::DeviceKind::kMouse; - default: - FML_DLOG(INFO) << "Unhandled touch type: " << touch.type; - break; - } + switch (touch.type) { + case UITouchTypeDirect: + case UITouchTypeIndirect: + return flutter::PointerData::DeviceKind::kTouch; + case UITouchTypeStylus: + return flutter::PointerData::DeviceKind::kStylus; + case UITouchTypeIndirectPointer: + return flutter::PointerData::DeviceKind::kMouse; + default: + FML_DLOG(INFO) << "Unhandled touch type: " << touch.type; + break; } return flutter::PointerData::DeviceKind::kTouch; @@ -1040,57 +1024,46 @@ - (void)dispatchTouches:(NSSet*)touches } // pressure_min is always 0.0 - if (@available(iOS 9, *)) { - // These properties were introduced in iOS 9.0. - pointer_data.pressure = touch.force; - pointer_data.pressure_max = touch.maximumPossibleForce; - } else { - pointer_data.pressure = 1.0; - pointer_data.pressure_max = 1.0; - } - - // These properties were introduced in iOS 8.0 + pointer_data.pressure = touch.force; + pointer_data.pressure_max = touch.maximumPossibleForce; pointer_data.radius_major = touch.majorRadius; pointer_data.radius_min = touch.majorRadius - touch.majorRadiusTolerance; pointer_data.radius_max = touch.majorRadius + touch.majorRadiusTolerance; - // These properties were introduced in iOS 9.1 - if (@available(iOS 9.1, *)) { - // iOS Documentation: altitudeAngle - // A value of 0 radians indicates that the stylus is parallel to the surface. The value of - // this property is Pi/2 when the stylus is perpendicular to the surface. - // - // PointerData Documentation: tilt - // The angle of the stylus, in radians in the range: - // 0 <= tilt <= pi/2 - // giving the angle of the axis of the stylus, relative to the axis perpendicular to the input - // surface (thus 0.0 indicates the stylus is orthogonal to the plane of the input surface, - // while pi/2 indicates that the stylus is flat on that surface). - // - // Discussion: - // The ranges are the same. Origins are swapped. - pointer_data.tilt = M_PI_2 - touch.altitudeAngle; - - // iOS Documentation: azimuthAngleInView: - // With the tip of the stylus touching the screen, the value of this property is 0 radians - // when the cap end of the stylus (that is, the end opposite of the tip) points along the - // positive x axis of the device's screen. The azimuth angle increases as the user swings the - // cap end of the stylus in a clockwise direction around the tip. - // - // PointerData Documentation: orientation - // The angle of the stylus, in radians in the range: - // -pi < orientation <= pi - // giving the angle of the axis of the stylus projected onto the input surface, relative to - // the positive y-axis of that surface (thus 0.0 indicates the stylus, if projected onto that - // surface, would go from the contact point vertically up in the positive y-axis direction, pi - // would indicate that the stylus would go down in the negative y-axis direction; pi/4 would - // indicate that the stylus goes up and to the right, -pi/2 would indicate that the stylus - // goes to the left, etc). - // - // Discussion: - // Sweep direction is the same. Phase of M_PI_2. - pointer_data.orientation = [touch azimuthAngleInView:nil] - M_PI_2; - } + // iOS Documentation: altitudeAngle + // A value of 0 radians indicates that the stylus is parallel to the surface. The value of + // this property is Pi/2 when the stylus is perpendicular to the surface. + // + // PointerData Documentation: tilt + // The angle of the stylus, in radians in the range: + // 0 <= tilt <= pi/2 + // giving the angle of the axis of the stylus, relative to the axis perpendicular to the input + // surface (thus 0.0 indicates the stylus is orthogonal to the plane of the input surface, + // while pi/2 indicates that the stylus is flat on that surface). + // + // Discussion: + // The ranges are the same. Origins are swapped. + pointer_data.tilt = M_PI_2 - touch.altitudeAngle; + + // iOS Documentation: azimuthAngleInView: + // With the tip of the stylus touching the screen, the value of this property is 0 radians + // when the cap end of the stylus (that is, the end opposite of the tip) points along the + // positive x axis of the device's screen. The azimuth angle increases as the user swings the + // cap end of the stylus in a clockwise direction around the tip. + // + // PointerData Documentation: orientation + // The angle of the stylus, in radians in the range: + // -pi < orientation <= pi + // giving the angle of the axis of the stylus projected onto the input surface, relative to + // the positive y-axis of that surface (thus 0.0 indicates the stylus, if projected onto that + // surface, would go from the contact point vertically up in the positive y-axis direction, pi + // would indicate that the stylus would go down in the negative y-axis direction; pi/4 would + // indicate that the stylus goes up and to the right, -pi/2 would indicate that the stylus + // goes to the left, etc). + // + // Discussion: + // Sweep direction is the same. Phase of M_PI_2. + pointer_data.orientation = [touch azimuthAngleInView:nil] - M_PI_2; if (@available(iOS 13.4, *)) { if (event != nullptr) { @@ -1207,14 +1180,10 @@ - (void)viewSafeAreaInsetsDidChange { // Viewport padding represents the iOS safe area insets. - (void)updateViewportPadding { CGFloat scale = [UIScreen mainScreen].scale; - if (@available(iOS 11, *)) { - _viewportMetrics.physical_padding_top = self.view.safeAreaInsets.top * scale; - _viewportMetrics.physical_padding_left = self.view.safeAreaInsets.left * scale; - _viewportMetrics.physical_padding_right = self.view.safeAreaInsets.right * scale; - _viewportMetrics.physical_padding_bottom = self.view.safeAreaInsets.bottom * scale; - } else { - _viewportMetrics.physical_padding_top = [self statusBarPadding] * scale; - } + _viewportMetrics.physical_padding_top = self.view.safeAreaInsets.top * scale; + _viewportMetrics.physical_padding_left = self.view.safeAreaInsets.left * scale; + _viewportMetrics.physical_padding_right = self.view.safeAreaInsets.right * scale; + _viewportMetrics.physical_padding_bottom = self.view.safeAreaInsets.bottom * scale; } #pragma mark - Keyboard events @@ -1222,12 +1191,10 @@ - (void)updateViewportPadding { - (void)keyboardWillChangeFrame:(NSNotification*)notification { NSDictionary* info = [notification userInfo]; - if (@available(iOS 9, *)) { - // Ignore keyboard notifications related to other apps. - id isLocal = info[UIKeyboardIsLocalUserInfoKey]; - if (isLocal && ![isLocal boolValue]) { - return; - } + // Ignore keyboard notifications related to other apps. + id isLocal = info[UIKeyboardIsLocalUserInfoKey]; + if (isLocal && ![isLocal boolValue]) { + return; } // Ignore keyboard notifications if engine’s viewController is not current viewController. @@ -1260,12 +1227,10 @@ - (void)keyboardWillChangeFrame:(NSNotification*)notification { - (void)keyboardWillBeHidden:(NSNotification*)notification { NSDictionary* info = [notification userInfo]; - if (@available(iOS 9, *)) { - // Ignore keyboard notifications related to other apps. - id isLocal = info[UIKeyboardIsLocalUserInfoKey]; - if (isLocal && ![isLocal boolValue]) { - return; - } + // Ignore keyboard notifications related to other apps. + id isLocal = info[UIKeyboardIsLocalUserInfoKey]; + if (isLocal && ![isLocal boolValue]) { + return; } // Ignore keyboard notifications if engine’s viewController is not current viewController. @@ -1504,9 +1469,7 @@ - (void)onShowHomeIndicatorNotification:(NSNotification*)notification { - (void)setIsHomeIndicatorHidden:(BOOL)hideHomeIndicator { if (hideHomeIndicator != _isHomeIndicatorHidden) { _isHomeIndicatorHidden = hideHomeIndicator; - if (@available(iOS 11, *)) { - [self setNeedsUpdateOfHomeIndicatorAutoHidden]; - } + [self setNeedsUpdateOfHomeIndicatorAutoHidden]; } } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index a2da6089aebb0..c6b1a1166942e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -101,20 +101,6 @@ - (void)setViewController:(FlutterViewController*)viewController { } @end -// The following conditional compilation defines an API 13 concept on earlier API targets so that -// a compiler compiling against API 12 or below does not blow up due to non-existent members. -#if __IPHONE_OS_VERSION_MAX_ALLOWED < 130000 -typedef enum UIAccessibilityContrast : NSInteger { - UIAccessibilityContrastUnspecified = 0, - UIAccessibilityContrastNormal = 1, - UIAccessibilityContrastHigh = 2 -} UIAccessibilityContrast; - -@interface UITraitCollection (MethodsFromNewerSDK) -- (UIAccessibilityContrast)accessibilityContrast; -@end -#endif - @interface FlutterKeyboardManager (Tests) @property(nonatomic, retain, readonly) NSMutableArray>* primaryResponders; diff --git a/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm b/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm index e264644c2bd25..3fe74a05a9fe6 100644 --- a/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm +++ b/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm @@ -47,7 +47,7 @@ - (void)testSetCorrectVariableRefreshRates { XCTAssertEqual(link.preferredFrameRateRange.maximum, maxFrameRate); XCTAssertEqual(link.preferredFrameRateRange.preferred, maxFrameRate); XCTAssertEqual(link.preferredFrameRateRange.minimum, maxFrameRate / 2); - } else if (@available(iOS 10.0, *)) { + } else { XCTAssertEqual(link.preferredFramesPerSecond, maxFrameRate); } [vsyncClient release]; @@ -70,7 +70,7 @@ - (void)testDoNotSetVariableRefreshRatesIfCADisableMinimumFrameDurationOnPhoneIs XCTAssertEqual(link.preferredFrameRateRange.maximum, 0); XCTAssertEqual(link.preferredFrameRateRange.preferred, 0); XCTAssertEqual(link.preferredFrameRateRange.minimum, 0); - } else if (@available(iOS 10.0, *)) { + } else { XCTAssertEqual(link.preferredFramesPerSecond, 0); } [vsyncClient release]; @@ -89,7 +89,7 @@ - (void)testDoNotSetVariableRefreshRatesIfCADisableMinimumFrameDurationOnPhoneIs XCTAssertEqual(link.preferredFrameRateRange.maximum, 0); XCTAssertEqual(link.preferredFrameRateRange.preferred, 0); XCTAssertEqual(link.preferredFrameRateRange.minimum, 0); - } else if (@available(iOS 10.0, *)) { + } else { XCTAssertEqual(link.preferredFramesPerSecond, 0); } [vsyncClient release]; diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index f0f8444025a14..08dbb1d241380 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -134,17 +134,12 @@ void PostAccessibilityNotification(UIAccessibilityNotifications notification, // Android. NSString* announcement = [[[NSString alloc] initWithUTF8String:object.node.label.c_str()] autorelease]; - if (@available(iOS 11.0, *)) { - UIAccessibilityPostNotification( - UIAccessibilityAnnouncementNotification, - [[[NSAttributedString alloc] - initWithString:announcement - attributes:@{ - UIAccessibilitySpeechAttributeQueueAnnouncement : @YES - }] autorelease]); - } else { - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, announcement); - } + UIAccessibilityPostNotification( + UIAccessibilityAnnouncementNotification, + [[[NSAttributedString alloc] initWithString:announcement + attributes:@{ + UIAccessibilitySpeechAttributeQueueAnnouncement : @YES + }] autorelease]); } } diff --git a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm index e635872010815..0e6b2f5e68dad 100644 --- a/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm +++ b/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm @@ -87,7 +87,7 @@ - (void)setMaxRefreshRateIfEnabled { if (@available(iOS 15.0, *)) { display_link_.get().preferredFrameRateRange = CAFrameRateRangeMake(minFrameRate, maxFrameRate, maxFrameRate); - } else if (@available(iOS 10.0, *)) { + } else { display_link_.get().preferredFramesPerSecond = maxFrameRate; } } @@ -102,12 +102,7 @@ - (void)onDisplayLink:(CADisplayLink*)link { CFTimeInterval delay = CACurrentMediaTime() - link.timestamp; fml::TimePoint frame_start_time = fml::TimePoint::Now() - fml::TimeDelta::FromSecondsF(delay); - CFTimeInterval duration; - if (@available(iOS 10.0, *)) { - duration = link.targetTimestamp - link.timestamp; - } else { - duration = link.duration; - } + CFTimeInterval duration = link.targetTimestamp - link.timestamp; fml::TimePoint frame_target_time = frame_start_time + fml::TimeDelta::FromSecondsF(duration); std::unique_ptr recorder = @@ -143,27 +138,23 @@ - (CADisplayLink*)getDisplayLink { @implementation DisplayLinkManager + (double)displayRefreshRate { - if (@available(iOS 10.3, *)) { - fml::scoped_nsobject display_link = fml::scoped_nsobject { - [[CADisplayLink displayLinkWithTarget:[[[DisplayLinkManager alloc] init] autorelease] - selector:@selector(onDisplayLink:)] retain] - }; - display_link.get().paused = YES; - auto preferredFPS = display_link.get().preferredFramesPerSecond; // iOS 10.0 - - // From Docs: - // The default value for preferredFramesPerSecond is 0. When this value is 0, the preferred - // frame rate is equal to the maximum refresh rate of the display, as indicated by the - // maximumFramesPerSecond property. + fml::scoped_nsobject display_link = fml::scoped_nsobject { + [[CADisplayLink displayLinkWithTarget:[[[DisplayLinkManager alloc] init] autorelease] + selector:@selector(onDisplayLink:)] retain] + }; + display_link.get().paused = YES; + auto preferredFPS = display_link.get().preferredFramesPerSecond; - if (preferredFPS != 0) { - return preferredFPS; - } + // From Docs: + // The default value for preferredFramesPerSecond is 0. When this value is 0, the preferred + // frame rate is equal to the maximum refresh rate of the display, as indicated by the + // maximumFramesPerSecond property. - return [UIScreen mainScreen].maximumFramesPerSecond; // iOS 10.3 - } else { - return 60.0; + if (preferredFPS != 0) { + return preferredFPS; } + + return [UIScreen mainScreen].maximumFramesPerSecond; } - (void)onDisplayLink:(CADisplayLink*)link { diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 61b9c3aeaadfa..5b6dfc3d95d9c 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -231,15 +231,13 @@ std::unique_ptr> out = std::make_unique>(); if (result != nullptr && [result count] > 0) { - if (@available(ios 10.0, *)) { - NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]]; - NSString* languageCode = [locale languageCode]; - out->emplace_back(languageCode == nullptr ? "" : languageCode.UTF8String); - NSString* countryCode = [locale countryCode]; - out->emplace_back(countryCode == nullptr ? "" : countryCode.UTF8String); - NSString* scriptCode = [locale scriptCode]; - out->emplace_back(scriptCode == nullptr ? "" : scriptCode.UTF8String); - } + NSLocale* locale = [NSLocale localeWithLocaleIdentifier:[result firstObject]]; + NSString* languageCode = [locale languageCode]; + out->emplace_back(languageCode == nullptr ? "" : languageCode.UTF8String); + NSString* countryCode = [locale countryCode]; + out->emplace_back(countryCode == nullptr ? "" : countryCode.UTF8String); + NSString* scriptCode = [locale scriptCode]; + out->emplace_back(scriptCode == nullptr ? "" : scriptCode.UTF8String); } return out; } diff --git a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm index 1f70690d9d4a1..21917a72ed1dd 100644 --- a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm +++ b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm @@ -181,17 +181,14 @@ .target = native_node, .user_info = nil, }); - if (@available(macOS 10.11, *)) { - if (ax_node.data().HasState(ax::mojom::State::kEditable)) { - events.push_back({ - .name = NSAccessibilityValueChangedNotification, - .target = - bridge->GetFlutterPlatformNodeDelegateFromID(AccessibilityBridge::kRootNodeId) - .lock() - ->GetNativeViewAccessible(), - .user_info = nil, - }); - } + if (ax_node.data().HasState(ax::mojom::State::kEditable)) { + events.push_back({ + .name = NSAccessibilityValueChangedNotification, + .target = bridge->GetFlutterPlatformNodeDelegateFromID(AccessibilityBridge::kRootNodeId) + .lock() + ->GetNativeViewAccessible(), + .user_info = nil, + }); } break; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 2962164c65426..040d22649e4ff 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -380,10 +380,8 @@ - (void)loadView { - (void)viewDidLoad { [self configureTrackingArea]; - if (@available(macOS 10.12.2, *)) { - [self.view setAllowedTouchTypes:NSTouchTypeMaskIndirect]; - [self.view setWantsRestingTouches:YES]; - } + [self.view setAllowedTouchTypes:NSTouchTypeMaskIndirect]; + [self.view setWantsRestingTouches:YES]; } - (void)viewWillAppear { @@ -841,28 +839,25 @@ - (void)swipeWithEvent:(NSEvent*)event { } - (void)touchesBeganWithEvent:(NSEvent*)event { - if (@available(macOS 10.12, *)) { - NSTouch* touch = event.allTouches.anyObject; - if (touch != nil) { - if (_mouseState.system_scroll_inertia_active) { - // The trackpad has been touched and a scroll gesture is still sending inertia events. - // A scroll inertia cancel message should be sent to the framework. - NSPoint locationInView = [self.flutterView convertPoint:event.locationInWindow - fromView:nil]; - NSPoint locationInBackingCoordinates = - [self.flutterView convertPointToBacking:locationInView]; - FlutterPointerEvent flutterEvent = { - .struct_size = sizeof(flutterEvent), - .timestamp = static_cast(event.timestamp * USEC_PER_SEC), - .x = locationInBackingCoordinates.x, - .y = -locationInBackingCoordinates.y, // convertPointToBacking makes this negative. - .device = kPointerPanZoomDeviceId, - .signal_kind = kFlutterPointerSignalKindScrollInertiaCancel, - .device_kind = kFlutterPointerDeviceKindTrackpad, - }; - - [_engine sendPointerEvent:flutterEvent]; - } + NSTouch* touch = event.allTouches.anyObject; + if (touch != nil) { + if (_mouseState.system_scroll_inertia_active) { + // The trackpad has been touched and a scroll gesture is still sending inertia events. + // A scroll inertia cancel message should be sent to the framework. + NSPoint locationInView = [self.flutterView convertPoint:event.locationInWindow fromView:nil]; + NSPoint locationInBackingCoordinates = + [self.flutterView convertPointToBacking:locationInView]; + FlutterPointerEvent flutterEvent = { + .struct_size = sizeof(flutterEvent), + .timestamp = static_cast(event.timestamp * USEC_PER_SEC), + .x = locationInBackingCoordinates.x, + .y = -locationInBackingCoordinates.y, // convertPointToBacking makes this negative. + .device = kPointerPanZoomDeviceId, + .signal_kind = kFlutterPointerSignalKindScrollInertiaCancel, + .device_kind = kFlutterPointerDeviceKindTrackpad, + }; + + [_engine sendPointerEvent:flutterEvent]; } } } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm index 3a356eb0083a7..09e047ce15478 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm @@ -485,47 +485,45 @@ - (bool)testTrackpadGesturesAreSentToFramework { EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad); EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone); - if (@available(macOS 10.12, *)) { - // Start system momentum. - CGEventRef cgEventMomentumStart = CGEventCreateCopy(cgEventStart); - CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventScrollPhase, 0); - CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventMomentumPhase, - kCGMomentumScrollPhaseBegin); - - called = false; - [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumStart]]; - EXPECT_FALSE(called); - - // Mock a touch on the trackpad. - id touchMock = OCMClassMock([NSTouch class]); - NSSet* touchSet = [NSSet setWithObject:touchMock]; - id touchEventMock = OCMClassMock([NSEvent class]); - OCMStub([touchEventMock allTouches]).andReturn(touchSet); - CGPoint touchLocation = {0, 0}; - OCMStub([touchEventMock locationInWindow]).andReturn(touchLocation); - - // Scroll inertia cancel event should be issued. - called = false; - [viewController touchesBeganWithEvent:touchEventMock]; - EXPECT_TRUE(called); - EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindScrollInertiaCancel); - EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad); - - // End system momentum. - CGEventRef cgEventMomentumEnd = CGEventCreateCopy(cgEventStart); - CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventScrollPhase, 0); - CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventMomentumPhase, - kCGMomentumScrollPhaseEnd); - - called = false; - [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumEnd]]; - EXPECT_FALSE(called); - - // Scroll inertia cancel event should not be issued after momentum has ended. - called = false; - [viewController touchesBeganWithEvent:touchEventMock]; - EXPECT_FALSE(called); - } + // Start system momentum. + CGEventRef cgEventMomentumStart = CGEventCreateCopy(cgEventStart); + CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventScrollPhase, 0); + CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventMomentumPhase, + kCGMomentumScrollPhaseBegin); + + called = false; + [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumStart]]; + EXPECT_FALSE(called); + + // Mock a touch on the trackpad. + id touchMock = OCMClassMock([NSTouch class]); + NSSet* touchSet = [NSSet setWithObject:touchMock]; + id touchEventMock = OCMClassMock([NSEvent class]); + OCMStub([touchEventMock allTouches]).andReturn(touchSet); + CGPoint touchLocation = {0, 0}; + OCMStub([touchEventMock locationInWindow]).andReturn(touchLocation); + + // Scroll inertia cancel event should be issued. + called = false; + [viewController touchesBeganWithEvent:touchEventMock]; + EXPECT_TRUE(called); + EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindScrollInertiaCancel); + EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad); + + // End system momentum. + CGEventRef cgEventMomentumEnd = CGEventCreateCopy(cgEventStart); + CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventScrollPhase, 0); + CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventMomentumPhase, + kCGMomentumScrollPhaseEnd); + + called = false; + [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumEnd]]; + EXPECT_FALSE(called); + + // Scroll inertia cancel event should not be issued after momentum has ended. + called = false; + [viewController touchesBeganWithEvent:touchEventMock]; + EXPECT_FALSE(called); // May-begin and cancel are used while macOS determines which type of gesture to choose. CGEventRef cgEventMayBegin = CGEventCreateCopy(cgEventStart); From 9b46de4f0bc9745573eb3d8be26389be066b1115 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 26 Jul 2022 11:46:45 -0700 Subject: [PATCH 2/3] Roll back MAC_OS_VERSION_12_0 --- .../renderer/backend/metal/command_buffer_mtl.mm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.mm b/impeller/renderer/backend/metal/command_buffer_mtl.mm index dd3901f46addf..e7d6c56199449 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/command_buffer_mtl.mm @@ -27,6 +27,18 @@ return @"unknown"; } +// NOLINTBEGIN(readability-identifier-naming) + +// TODO(dnfield): This can be removed when all bots have been sufficiently +// upgraded for MAC_OS_VERSION_12_0. +#if !defined(MAC_OS_VERSION_12_0) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0 +constexpr int MTLCommandBufferErrorAccessRevoked = 4; +constexpr int MTLCommandBufferErrorStackOverflow = 12; +#endif + +// NOLINTEND(readability-identifier-naming) + static NSString* MTLCommandBufferErrorToString(MTLCommandBufferError code) { switch (code) { case MTLCommandBufferErrorNone: From 7f6dbe905951d34dfeee578dc9a9ddeb0c8e412c Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 26 Jul 2022 11:47:48 -0700 Subject: [PATCH 3/3] Format --- .../darwin/ios/framework/Source/FlutterPlatformPlugin.mm | 2 +- .../platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 6d9e2d7114c2d..88143fffde33a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -17,7 +17,7 @@ constexpr char kTextPlainFormat[] = "text/plain"; const UInt32 kKeyPressClickSoundId = 1306; -} // namespaces +} // namespace namespace flutter { diff --git a/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm b/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm index 3fe74a05a9fe6..124bdee2e8441 100644 --- a/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm +++ b/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm @@ -17,7 +17,7 @@ auto runner = thread->GetTaskRunner(); return runner; } -} +} // namespace @interface VSyncClient (Testing)