Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
FlutterDartProject.mm File Reference
import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
import <Metal/Metal.h>
import <UIKit/UIKit.h>
#include <sstream>
#include "flutter/common/constants.h"
#include "flutter/fml/build_config.h"
#include "flutter/shell/common/switches.h"
import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
#include "flutter/shell/platform/darwin/common/command_line.h"

Go to the source code of this file.

Macros

#define FML_USED_ON_EMBEDDER
 

Functions

static BOOL DoesHardwareSupportWideGamut ()
 
NSNumber *_Nullable FLTEnableWideGamutFromBundle (NSBundle *_Nullable bundle, NSBundle *_Nullable mainBundle)
 
flutter::Settings FLTDefaultSettingsForBundle (NSBundle *bundle, NSProcessInfo *processInfoOrNil)
 

Variables

FLUTTER_ASSERT_ARC const uint8_t kPlatformStrongDill []
 
const intptr_t kPlatformStrongDillSize
 
static const char * kApplicationKernelSnapshotFileName = "kernel_blob.bin"
 

Macro Definition Documentation

◆ FML_USED_ON_EMBEDDER

#define FML_USED_ON_EMBEDDER

Definition at line 5 of file FlutterDartProject.mm.

Function Documentation

◆ DoesHardwareSupportWideGamut()

static BOOL DoesHardwareSupportWideGamut ( )
static

Definition at line 32 of file FlutterDartProject.mm.

32 {
33 static BOOL result = NO;
34 static dispatch_once_t once_token = 0;
35 dispatch_once(&once_token, ^{
36 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
37 result = [device supportsFamily:MTLGPUFamilyApple2];
38 });
39 return result;
40}
VkDevice device
Definition main.cc:69
int BOOL

References device.

Referenced by FlutterDartProject::defaultBundleIdentifier.

◆ FLTDefaultSettingsForBundle()

flutter::Settings FLTDefaultSettingsForBundle ( NSBundle *  bundle,
NSProcessInfo *  processInfoOrNil 
)

Definition at line 51 of file FlutterDartProject.mm.

51 {
52 auto command_line = flutter::CommandLineFromNSProcessInfo(processInfoOrNil);
53
54 // Precedence:
55 // 1. Settings from the specified NSBundle.
56 // 2. Settings passed explicitly via command-line arguments.
57 // 3. Settings from the NSBundle with the default bundle ID.
58 // 4. Settings from the main NSBundle and default values.
59
60 NSBundle* mainBundle = FLTGetApplicationBundle();
61 NSBundle* engineBundle = [NSBundle bundleForClass:[FlutterDartProject class]];
62
63 bool hasExplicitBundle = bundle != nil;
64 if (bundle == nil) {
65 bundle = FLTFrameworkBundleWithIdentifier([FlutterDartProject defaultBundleIdentifier]);
66 }
67
68 auto settings = flutter::SettingsFromCommandLine(command_line, true);
69
70 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
73 return queue_id;
74 };
75
76 settings.task_observer_remove = [](fml::TaskQueueId queue_id, intptr_t key) {
78 };
79
80 settings.log_message_callback = [](const std::string& tag, const std::string& message) {
81 std::stringstream stream;
82 if (!tag.empty()) {
83 stream << tag << ": ";
84 }
85 stream << message;
86 std::string log = stream.str();
87 [FlutterLogger logDirect:[NSString stringWithUTF8String:log.c_str()]];
88 };
89
90 settings.enable_platform_isolates = true;
91
92 // The command line arguments may not always be complete. If they aren't, attempt to fill in
93 // defaults.
94
95 // Flutter ships the ICU data file in the bundle of the engine. Look for it there.
96 if (settings.icu_data_path.empty()) {
97 NSString* icuDataPath = [engineBundle pathForResource:@"icudtl" ofType:@"dat"];
98 if (icuDataPath.length > 0) {
99 settings.icu_data_path = icuDataPath.UTF8String;
100 }
101 }
102
104 if (hasExplicitBundle) {
105 NSString* executablePath = bundle.executablePath;
106 if ([[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
107 settings.application_library_paths.push_back(executablePath.UTF8String);
108 }
109 }
110
111 // No application bundle specified. Try a known location from the main bundle's Info.plist.
112 if (settings.application_library_paths.empty()) {
113 NSString* libraryName = [mainBundle objectForInfoDictionaryKey:@"FLTLibraryPath"];
114 NSString* libraryPath = [mainBundle pathForResource:libraryName ofType:@""];
115 if (libraryPath.length > 0) {
116 NSString* executablePath = [NSBundle bundleWithPath:libraryPath].executablePath;
117 if (executablePath.length > 0) {
118 settings.application_library_paths.push_back(executablePath.UTF8String);
119 }
120 }
121 }
122
123 // In case the application bundle is still not specified, look for the App.framework in the
124 // Frameworks directory.
125 if (settings.application_library_paths.empty()) {
126 NSString* applicationFrameworkPath = [mainBundle pathForResource:@"Frameworks/App.framework"
127 ofType:@""];
128 if (applicationFrameworkPath.length > 0) {
129 NSString* executablePath =
130 [NSBundle bundleWithPath:applicationFrameworkPath].executablePath;
131 if (executablePath.length > 0) {
132 settings.application_library_paths.push_back(executablePath.UTF8String);
133 }
134 }
135 }
136 }
137
138 // Checks to see if the flutter assets directory is already present.
139 if (settings.assets_path.empty()) {
140 NSString* assetsPath = FLTAssetsPathFromBundle(bundle);
141
142 if (assetsPath.length == 0) {
143 NSLog(@"Failed to find assets path for \"%@\"", bundle);
144 } else {
145 settings.assets_path = assetsPath.UTF8String;
146
147 // Check if there is an application kernel snapshot in the assets directory we could
148 // potentially use. Looking for the snapshot makes sense only if we have a VM that can use
149 // it.
151 NSURL* applicationKernelSnapshotURL =
152 [NSURL URLWithString:@(kApplicationKernelSnapshotFileName)
153 relativeToURL:[NSURL fileURLWithPath:assetsPath]];
154 NSError* error;
155 if ([applicationKernelSnapshotURL checkResourceIsReachableAndReturnError:&error]) {
156 settings.application_kernel_asset = applicationKernelSnapshotURL.path.UTF8String;
157 } else {
158 NSLog(@"Failed to find snapshot at %@: %@", applicationKernelSnapshotURL.path, error);
159 }
160 }
161 }
162 }
163
164 // Domain network configuration
165 // Disabled in https://github.com/flutter/flutter/issues/72723.
166 // Re-enable in https://github.com/flutter/flutter/issues/54448.
167 settings.may_insecurely_connect_to_all_domains = true;
168 settings.domain_network_policy = "";
169
170 // Whether to enable wide gamut colors.
171#if TARGET_OS_SIMULATOR
172 // As of Xcode 14.1, the wide gamut surface pixel formats are not supported by
173 // the simulator.
174 settings.enable_wide_gamut = false;
175 // Removes unused function warning.
177#else
178 NSNumber* nsEnableWideGamut = FLTEnableWideGamutFromBundle(bundle, mainBundle);
179 BOOL enableWideGamut =
180 (nsEnableWideGamut ? nsEnableWideGamut.boolValue : YES) && DoesHardwareSupportWideGamut();
181 settings.enable_wide_gamut = enableWideGamut;
182#endif
183
184 NSNumber* nsAntialiasLines = [mainBundle objectForInfoDictionaryKey:@"FLTAntialiasLines"];
185 settings.impeller_antialiased_lines = (nsAntialiasLines ? nsAntialiasLines.boolValue : NO);
186
187 settings.warn_on_impeller_opt_out = true;
188
189 NSNumber* nsEnableSDFs = [mainBundle objectForInfoDictionaryKey:@"FLTEnableSDFs"];
190 settings.impeller_use_sdfs = (nsEnableSDFs ? nsEnableSDFs.boolValue : NO);
191
192 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"];
193 // Change the default only if the option is present.
194 if (enableTraceSystrace != nil) {
195 settings.trace_systrace = enableTraceSystrace.boolValue;
196 }
197
198 NSNumber* profileMicrotasks = [mainBundle objectForInfoDictionaryKey:@"FLTProfileMicrotasks"];
199 // Change the default only if the option is present.
200 if (profileMicrotasks != nil) {
201 settings.profile_microtasks = profileMicrotasks.boolValue;
202 }
203
204 NSNumber* enableDartAsserts = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartAsserts"];
205 if (enableDartAsserts != nil) {
206 settings.dart_flags.push_back("--enable-asserts");
207 }
208
209 NSNumber* enableDartProfiling = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartProfiling"];
210 // Change the default only if the option is present.
211 if (enableDartProfiling != nil) {
212 settings.enable_dart_profiling = enableDartProfiling.boolValue;
213 }
214
215 NSNumber* profileStartup = [mainBundle objectForInfoDictionaryKey:@"FLTProfileStartup"];
216 // Change the default only if the option is present.
217 if (profileStartup != nil) {
218 settings.profile_startup = profileStartup.boolValue;
219 }
220
221 // Leak Dart VM settings, set whether leave or clean up the VM after the last shell shuts down.
222 NSNumber* leakDartVM = [mainBundle objectForInfoDictionaryKey:@"FLTLeakDartVM"];
223 // It will change the default leak_vm value in settings only if the key exists.
224 if (leakDartVM != nil) {
225 settings.leak_vm = leakDartVM.boolValue;
226 }
227
228 NSNumber* enableMergedPlatformUIThread =
229 [mainBundle objectForInfoDictionaryKey:@"FLTEnableMergedPlatformUIThread"];
230 if (enableMergedPlatformUIThread != nil) {
231 FML_CHECK(enableMergedPlatformUIThread.boolValue)
232 << "FLTEnableMergedPlatformUIThread=false is no longer allowed.";
233 }
234
235 NSNumber* enableFlutterGPU = [mainBundle objectForInfoDictionaryKey:@"FLTEnableFlutterGPU"];
236 if (enableFlutterGPU != nil) {
237 settings.enable_flutter_gpu = enableFlutterGPU.boolValue;
238 }
239
240#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
241 // There are no ownership concerns here as all mappings are owned by the
242 // embedder and not the engine.
243 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
244 return [mapping, size]() { return std::make_unique<fml::NonOwnedMapping>(mapping, size); };
245 };
246
247 settings.dart_library_sources_kernel =
248 make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
249#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
250
251 // If we even support setting this e.g. from the command line or the plist,
252 // we should let the user override it.
253 // Otherwise, we want to set this to a value that will avoid having the OS
254 // kill us. On most iOS devices, that happens somewhere near half
255 // the available memory.
256 // The VM expects this value to be in megabytes.
257 if (settings.old_gen_heap_size <= 0) {
258 settings.old_gen_heap_size = std::round([NSProcessInfo processInfo].physicalMemory * .48 /
260 }
261
262 // This is the formula Android uses.
263 // https://android.googlesource.com/platform/frameworks/base/+/39ae5bac216757bc201490f4c7b8c0f63006c6cd/libs/hwui/renderthread/CacheManager.cpp#45
264 CGFloat scale = [UIScreen mainScreen].scale;
265 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width * scale;
266 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height * scale;
267 settings.resource_cache_max_bytes_threshold = screenWidth * screenHeight * 12 * 4;
268
269 // Whether to enable ios embedder api.
270 NSNumber* enable_embedder_api =
271 [mainBundle objectForInfoDictionaryKey:@"FLTEnableIOSEmbedderAPI"];
272 // Change the default only if the option is present.
273 if (enable_embedder_api) {
274 settings.enable_embedder_api = enable_embedder_api.boolValue;
275 }
276
277 return settings;
278}
NSBundle * FLTFrameworkBundleWithIdentifier(NSString *flutterFrameworkBundleID)
NSString * FLTAssetsPathFromBundle(NSBundle *bundle)
NSBundle * FLTGetApplicationBundle()
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition dart_vm.cc:177
static TaskQueueId GetCurrentTaskQueueId()
static MessageLoopTaskQueues * GetInstance()
void AddTaskObserver(TaskQueueId queue_id, intptr_t key, const fml::closure &callback)
void RemoveTaskObserver(TaskQueueId queue_id, intptr_t key)
const char * message
const uint8_t uint32_t uint32_t GError ** error
FlutterDesktopBinaryReply callback
#define FML_CHECK(condition)
Definition logging.h:104
NSNumber *_Nullable FLTEnableWideGamutFromBundle(NSBundle *_Nullable bundle, NSBundle *_Nullable mainBundle)
static const char * kApplicationKernelSnapshotFileName
const intptr_t kPlatformStrongDillSize
FLUTTER_ASSERT_ARC const uint8_t kPlatformStrongDill[]
static BOOL DoesHardwareSupportWideGamut()
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Settings SettingsFromCommandLine(const fml::CommandLine &command_line, bool require_merged_platform_ui_thread)
Definition switches.cc:230
fml::CommandLine CommandLineFromNSProcessInfo(NSProcessInfo *processInfoOrNil=nil)
constexpr double kMegaByteSizeInBytes
Definition constants.h:9
std::function< void()> closure
Definition closure.h:14

◆ FLTEnableWideGamutFromBundle()

NSNumber *_Nullable FLTEnableWideGamutFromBundle ( NSBundle *_Nullable  bundle,
NSBundle *_Nullable  mainBundle 
)

Returns the value of the FLTEnableWideGamut key from the given bundle, falling back to the main bundle if not found in the first. If both bundles are the same object, the value is read once.

Definition at line 42 of file FlutterDartProject.mm.

43 {
44 NSNumber* nsEnableWideGamut = [bundle objectForInfoDictionaryKey:@"FLTEnableWideGamut"];
45 if (nsEnableWideGamut == nil && bundle != mainBundle) {
46 nsEnableWideGamut = [mainBundle objectForInfoDictionaryKey:@"FLTEnableWideGamut"];
47 }
48 return nsEnableWideGamut;
49}

Referenced by FlutterDartProject::defaultBundleIdentifier.

Variable Documentation

◆ kApplicationKernelSnapshotFileName

const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin"
static

◆ kPlatformStrongDill

FLUTTER_ASSERT_ARC const uint8_t kPlatformStrongDill[]
extern

◆ kPlatformStrongDillSize

const intptr_t kPlatformStrongDillSize
extern