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 settings.warn_on_impeller_opt_out = true;
185
186 NSNumber* nsEnableSDFs = [mainBundle objectForInfoDictionaryKey:@"FLTEnableSDFs"];
187 settings.impeller_use_sdfs = (nsEnableSDFs ? nsEnableSDFs.boolValue : NO);
188
189 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"];
190 // Change the default only if the option is present.
191 if (enableTraceSystrace != nil) {
192 settings.trace_systrace = enableTraceSystrace.boolValue;
193 }
194
195 NSNumber* profileMicrotasks = [mainBundle objectForInfoDictionaryKey:@"FLTProfileMicrotasks"];
196 // Change the default only if the option is present.
197 if (profileMicrotasks != nil) {
198 settings.profile_microtasks = profileMicrotasks.boolValue;
199 }
200
201 NSNumber* enableDartAsserts = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartAsserts"];
202 if (enableDartAsserts != nil) {
203 settings.dart_flags.push_back("--enable-asserts");
204 }
205
206 NSNumber* enableDartProfiling = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartProfiling"];
207 // Change the default only if the option is present.
208 if (enableDartProfiling != nil) {
209 settings.enable_dart_profiling = enableDartProfiling.boolValue;
210 }
211
212 NSNumber* profileStartup = [mainBundle objectForInfoDictionaryKey:@"FLTProfileStartup"];
213 // Change the default only if the option is present.
214 if (profileStartup != nil) {
215 settings.profile_startup = profileStartup.boolValue;
216 }
217
218 // Leak Dart VM settings, set whether leave or clean up the VM after the last shell shuts down.
219 NSNumber* leakDartVM = [mainBundle objectForInfoDictionaryKey:@"FLTLeakDartVM"];
220 // It will change the default leak_vm value in settings only if the key exists.
221 if (leakDartVM != nil) {
222 settings.leak_vm = leakDartVM.boolValue;
223 }
224
225 NSNumber* enableMergedPlatformUIThread =
226 [mainBundle objectForInfoDictionaryKey:@"FLTEnableMergedPlatformUIThread"];
227 if (enableMergedPlatformUIThread != nil) {
228 FML_CHECK(enableMergedPlatformUIThread.boolValue)
229 << "FLTEnableMergedPlatformUIThread=false is no longer allowed.";
230 }
231
232 NSNumber* enableFlutterGPU = [mainBundle objectForInfoDictionaryKey:@"FLTEnableFlutterGPU"];
233 if (enableFlutterGPU != nil) {
234 settings.enable_flutter_gpu = enableFlutterGPU.boolValue;
235 }
236
237#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
238 // There are no ownership concerns here as all mappings are owned by the
239 // embedder and not the engine.
240 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
241 return [mapping, size]() { return std::make_unique<fml::NonOwnedMapping>(mapping, size); };
242 };
243
244 settings.dart_library_sources_kernel =
245 make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
246#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
247
248 // If we even support setting this e.g. from the command line or the plist,
249 // we should let the user override it.
250 // Otherwise, we want to set this to a value that will avoid having the OS
251 // kill us. On most iOS devices, that happens somewhere near half
252 // the available memory.
253 // The VM expects this value to be in megabytes.
254 if (settings.old_gen_heap_size <= 0) {
255 settings.old_gen_heap_size = std::round([NSProcessInfo processInfo].physicalMemory * .48 /
257 }
258
259 // This is the formula Android uses.
260 // https://android.googlesource.com/platform/frameworks/base/+/39ae5bac216757bc201490f4c7b8c0f63006c6cd/libs/hwui/renderthread/CacheManager.cpp#45
261 CGFloat scale = [UIScreen mainScreen].scale;
262 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width * scale;
263 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height * scale;
264 settings.resource_cache_max_bytes_threshold = screenWidth * screenHeight * 12 * 4;
265
266 // Whether to enable ios embedder api.
267 NSNumber* enable_embedder_api =
268 [mainBundle objectForInfoDictionaryKey:@"FLTEnableIOSEmbedderAPI"];
269 // Change the default only if the option is present.
270 if (enable_embedder_api) {
271 settings.enable_embedder_api = enable_embedder_api.boolValue;
272 }
273
274 return settings;
275}
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