diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 0dede34e2e..3bfaca823e 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -2093,7 +2093,7 @@ extern NSNotificationName const FlutterViewControllerWillDealloc; - (void)testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController { id bundleMock = OCMPartialMock([NSBundle mainBundle]); - OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"]) + OCMStub([bundleMock objectForInfoDictionaryKey:kCADisableMinimumFrameDurationOnPhoneKey]) .andReturn(@YES); id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]]; double maxFrameRate = 120; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm index cbe58384f6..4a547bf285 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/VsyncWaiterIosTest.mm @@ -53,7 +53,7 @@ fml::RefPtr CreateNewThread(const std::string& name) { auto thread_task_runner = CreateNewThread("VsyncWaiterIosTest"); auto callback = [](std::unique_ptr recorder) {}; id bundleMock = OCMPartialMock([NSBundle mainBundle]); - OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"]) + OCMStub([bundleMock objectForInfoDictionaryKey:kCADisableMinimumFrameDurationOnPhoneKey]) .andReturn(@YES); id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]]; double maxFrameRate = 120; @@ -75,7 +75,7 @@ fml::RefPtr CreateNewThread(const std::string& name) { auto thread_task_runner = CreateNewThread("VsyncWaiterIosTest"); auto callback = [](std::unique_ptr recorder) {}; id bundleMock = OCMPartialMock([NSBundle mainBundle]); - OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"]) + OCMStub([bundleMock objectForInfoDictionaryKey:kCADisableMinimumFrameDurationOnPhoneKey]) .andReturn(@NO); id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]]; double maxFrameRate = 120; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h index c4395f47a6..b9f575b87f 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h @@ -11,13 +11,24 @@ #include "flutter/shell/common/variable_refresh_rate_reporter.h" #include "flutter/shell/common/vsync_waiter.h" +//------------------------------------------------------------------------------ +/// @brief Info.plist key enabling the full range of ProMotion refresh rates for CADisplayLink +/// callbacks and CAAnimation animations in the app. +/// +/// @see +/// https://developer.apple.com/documentation/quartzcore/optimizing_promotion_refresh_rates_for_iphone_13_pro_and_ipad_pro#3885321 +/// +extern NSString* const kCADisableMinimumFrameDurationOnPhoneKey; + @interface DisplayLinkManager : NSObject -// Whether the max refresh rate on iPhone Pro-motion devices are enabled. -// This reflects the value of `CADisableMinimumFrameDurationOnPhone` in the -// info.plist file. -// -// Note on iPads that support Pro-motion, the max refresh rate is always enabled. +//------------------------------------------------------------------------------ +/// @brief Whether the max refresh rate on iPhone ProMotion devices are enabled. This reflects +/// the value of `CADisableMinimumFrameDurationOnPhone` in the info.plist file. On iPads +/// that support ProMotion, the max refresh rate is always enabled. +/// +/// @return YES if the max refresh rate on ProMotion devices is enabled. +/// @property(class, nonatomic, readonly) BOOL maxRefreshRateEnabledOnIPhone; //------------------------------------------------------------------------------ diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm index 3c27604d2a..8552295f3a 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm @@ -18,6 +18,8 @@ FLUTTER_ASSERT_ARC +NSString* const kCADisableMinimumFrameDurationOnPhoneKey = @"CADisableMinimumFrameDurationOnPhone"; + @interface VSyncClient () @property(nonatomic, assign, readonly) double refreshRate; @end @@ -170,7 +172,7 @@ double VsyncWaiterIOS::GetRefreshRate() const { } + (BOOL)maxRefreshRateEnabledOnIPhone { - return [[NSBundle.mainBundle objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"] + return [[NSBundle.mainBundle objectForInfoDictionaryKey:kCADisableMinimumFrameDurationOnPhoneKey] boolValue]; }