From 56060406cde49e6dac89a530d18a53c24ad0c7be Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 5 Apr 2023 15:48:48 -0700 Subject: [PATCH] Fix UIWindowSceneGeometryPreferencesIOS leak --- .../framework/Source/FlutterViewController.mm | 4 +- .../Source/FlutterViewControllerTest.mm | 74 ++++++++++--------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 77742b0114c9e..fcf9989762a5e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -1814,8 +1814,8 @@ - (void)performOrientationUpdate:(UIInterfaceOrientationMask)new_preferences { } UIWindowScene* windowScene = (UIWindowScene*)scene; UIWindowSceneGeometryPreferencesIOS* preference = - [[UIWindowSceneGeometryPreferencesIOS alloc] - initWithInterfaceOrientations:_orientationPreferences]; + [[[UIWindowSceneGeometryPreferencesIOS alloc] + initWithInterfaceOrientations:_orientationPreferences] autorelease]; [windowScene requestGeometryUpdateWithPreferences:preference errorHandler:^(NSError* error) { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 575215c2e77cb..4a5d6fd6176a9 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -1341,47 +1341,53 @@ - (void)orientationTestWithOrientationUpdate:(UIInterfaceOrientationMask)mask id mockApplication = OCMClassMock([UIApplication class]); id mockWindowScene; id deviceMock; - FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine - nibName:nil - bundle:nil]; - if (@available(iOS 16.0, *)) { - mockWindowScene = OCMClassMock([UIWindowScene class]); - if (realVC.supportedInterfaceOrientations == mask) { - OCMReject([mockWindowScene requestGeometryUpdateWithPreferences:[OCMArg any] - errorHandler:[OCMArg any]]); + __block __weak id weakPreferences; + @autoreleasepool { + FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine + nibName:nil + bundle:nil]; + if (@available(iOS 16.0, *)) { + mockWindowScene = OCMClassMock([UIWindowScene class]); + if (realVC.supportedInterfaceOrientations == mask) { + OCMReject([mockWindowScene requestGeometryUpdateWithPreferences:[OCMArg any] + errorHandler:[OCMArg any]]); + } else { + // iOS 16 will decide whether to rotate based on the new preference, so always set it + // when it changes. + OCMExpect([mockWindowScene + requestGeometryUpdateWithPreferences:[OCMArg checkWithBlock:^BOOL( + UIWindowSceneGeometryPreferencesIOS* + preferences) { + weakPreferences = preferences; + return preferences.interfaceOrientations == mask; + }] + errorHandler:[OCMArg any]]); + } + OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); + OCMStub([mockApplication connectedScenes]).andReturn([NSSet setWithObject:mockWindowScene]); } else { - // iOS 16 will decide whether to rotate based on the new preference, so always set it - // when it changes. - OCMExpect([mockWindowScene - requestGeometryUpdateWithPreferences:[OCMArg checkWithBlock:^BOOL( - UIWindowSceneGeometryPreferencesIOS* - preferences) { - return preferences.interfaceOrientations == mask; - }] - errorHandler:[OCMArg any]]); + deviceMock = OCMPartialMock([UIDevice currentDevice]); + if (!didChange) { + OCMReject([deviceMock setValue:[OCMArg any] forKey:@"orientation"]); + } else { + OCMExpect([deviceMock setValue:@(resultingOrientation) forKey:@"orientation"]); + } + + OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); + OCMStub([mockApplication statusBarOrientation]).andReturn(currentOrientation); } - OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); - OCMStub([mockApplication connectedScenes]).andReturn([NSSet setWithObject:mockWindowScene]); - } else { - deviceMock = OCMPartialMock([UIDevice currentDevice]); - if (!didChange) { - OCMReject([deviceMock setValue:[OCMArg any] forKey:@"orientation"]); + + [realVC performOrientationUpdate:mask]; + if (@available(iOS 16.0, *)) { + OCMVerifyAll(mockWindowScene); } else { - OCMExpect([deviceMock setValue:@(resultingOrientation) forKey:@"orientation"]); + OCMVerifyAll(deviceMock); } - - OCMStub([mockApplication sharedApplication]).andReturn(mockApplication); - OCMStub([mockApplication statusBarOrientation]).andReturn(currentOrientation); - } - - [realVC performOrientationUpdate:mask]; - if (@available(iOS 16.0, *)) { - OCMVerifyAll(mockWindowScene); - } else { - OCMVerifyAll(deviceMock); } + [mockWindowScene stopMocking]; [deviceMock stopMocking]; [mockApplication stopMocking]; + XCTAssertNil(weakPreferences); } // Creates a mocked UITraitCollection with nil values for everything except accessibilityContrast,