Read the FLTEnableImpeller flag from the right bundle (#40535)

diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
index 3c6f855..1830ad6 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
@@ -206,8 +206,12 @@
   BOOL enableWideGamut = nsEnableWideGamut ? nsEnableWideGamut.boolValue : NO;
   settings.enable_wide_gamut = enableWideGamut;
 
-  // Whether to enable Impeller.
-  NSNumber* enableImpeller = [mainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
+  // Whether to enable Impeller. First, look in the app bundle.
+  NSNumber* enableImpeller = [bundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
+  if (enableImpeller == nil) {
+    // If it isn't in the app bundle, look in the main bundle.
+    enableImpeller = [mainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
+  }
   // Change the default only if the option is present.
   if (enableImpeller != nil) {
     settings.enable_impeller = enableImpeller.boolValue;
diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm
index 8de0007..5092053 100644
--- a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm
+++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm
@@ -73,15 +73,54 @@
   XCTAssertNotNil(found);
 }
 
-- (void)testEnableImpellerSettingIsCorrectlyParsed {
-  // The FLTEnableImpeller's value is defined in Info.plist
-  NSBundle* mainBundle = [NSBundle mainBundle];
-  NSNumber* enableImpeller = [mainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
-  XCTAssertEqual(enableImpeller.boolValue, NO);
+- (void)testDisableImpellerSettingIsCorrectlyParsed {
+  id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
+  OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"NO");
 
   auto settings = FLTDefaultSettingsForBundle();
   // Check settings.enable_impeller value is same as the value defined in Info.plist.
   XCTAssertEqual(settings.enable_impeller, NO);
+  [mockMainBundle stopMocking];
+}
+
+- (void)testEnableImpellerSettingIsCorrectlyParsed {
+  id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
+  OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES");
+
+  auto settings = FLTDefaultSettingsForBundle();
+  // Check settings.enable_impeller value is same as the value defined in Info.plist.
+  XCTAssertEqual(settings.enable_impeller, YES);
+  [mockMainBundle stopMocking];
+}
+
+- (void)testDisableImpellerAppBundleSettingIsCorrectlyParsed {
+  NSString* bundleId = [FlutterDartProject defaultBundleIdentifier];
+  id mockAppBundle = OCMClassMock([NSBundle class]);
+  OCMStub([mockAppBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"NO");
+  OCMStub([mockAppBundle bundleWithIdentifier:bundleId]).andReturn(mockAppBundle);
+
+  auto settings = FLTDefaultSettingsForBundle();
+  // Check settings.enable_impeller value is same as the value defined in Info.plist.
+  XCTAssertEqual(settings.enable_impeller, NO);
+
+  [mockAppBundle stopMocking];
+}
+
+- (void)testEnableImpellerAppBundleSettingIsCorrectlyParsed {
+  NSString* bundleId = [FlutterDartProject defaultBundleIdentifier];
+  id mockAppBundle = OCMClassMock([NSBundle class]);
+  OCMStub([mockAppBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES");
+  OCMStub([mockAppBundle bundleWithIdentifier:bundleId]).andReturn(mockAppBundle);
+
+  // Since FLTEnableImpeller is set to false in the main bundle, this is also
+  // testing that setting FLTEnableImpeller in the app bundle takes
+  // precedence over setting it in the root bundle.
+
+  auto settings = FLTDefaultSettingsForBundle();
+  // Check settings.enable_impeller value is same as the value defined in Info.plist.
+  XCTAssertEqual(settings.enable_impeller, YES);
+
+  [mockAppBundle stopMocking];
 }
 
 - (void)testEnableTraceSystraceSettingIsCorrectlyParsed {