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 ()
 
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 42 of file FlutterDartProject.mm.

42 {
43 auto command_line = flutter::CommandLineFromNSProcessInfo(processInfoOrNil);
44
45 // Precedence:
46 // 1. Settings from the specified NSBundle.
47 // 2. Settings passed explicitly via command-line arguments.
48 // 3. Settings from the NSBundle with the default bundle ID.
49 // 4. Settings from the main NSBundle and default values.
50
51 NSBundle* mainBundle = FLTGetApplicationBundle();
52 NSBundle* engineBundle = [NSBundle bundleForClass:[FlutterDartProject class]];
53
54 bool hasExplicitBundle = bundle != nil;
55 if (bundle == nil) {
56 bundle = FLTFrameworkBundleWithIdentifier([FlutterDartProject defaultBundleIdentifier]);
57 }
58
59 auto settings = flutter::SettingsFromCommandLine(command_line, true);
60
61 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
64 return queue_id;
65 };
66
67 settings.task_observer_remove = [](fml::TaskQueueId queue_id, intptr_t key) {
69 };
70
71 settings.log_message_callback = [](const std::string& tag, const std::string& message) {
72 std::stringstream stream;
73 if (!tag.empty()) {
74 stream << tag << ": ";
75 }
76 stream << message;
77 std::string log = stream.str();
78 [FlutterLogger logDirect:[NSString stringWithUTF8String:log.c_str()]];
79 };
80
81 settings.enable_platform_isolates = true;
82
83 // The command line arguments may not always be complete. If they aren't, attempt to fill in
84 // defaults.
85
86 // Flutter ships the ICU data file in the bundle of the engine. Look for it there.
87 if (settings.icu_data_path.empty()) {
88 NSString* icuDataPath = [engineBundle pathForResource:@"icudtl" ofType:@"dat"];
89 if (icuDataPath.length > 0) {
90 settings.icu_data_path = icuDataPath.UTF8String;
91 }
92 }
93
95 if (hasExplicitBundle) {
96 NSString* executablePath = bundle.executablePath;
97 if ([[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
98 settings.application_library_paths.push_back(executablePath.UTF8String);
99 }
100 }
101
102 // No application bundle specified. Try a known location from the main bundle's Info.plist.
103 if (settings.application_library_paths.empty()) {
104 NSString* libraryName = [mainBundle objectForInfoDictionaryKey:@"FLTLibraryPath"];
105 NSString* libraryPath = [mainBundle pathForResource:libraryName ofType:@""];
106 if (libraryPath.length > 0) {
107 NSString* executablePath = [NSBundle bundleWithPath:libraryPath].executablePath;
108 if (executablePath.length > 0) {
109 settings.application_library_paths.push_back(executablePath.UTF8String);
110 }
111 }
112 }
113
114 // In case the application bundle is still not specified, look for the App.framework in the
115 // Frameworks directory.
116 if (settings.application_library_paths.empty()) {
117 NSString* applicationFrameworkPath = [mainBundle pathForResource:@"Frameworks/App.framework"
118 ofType:@""];
119 if (applicationFrameworkPath.length > 0) {
120 NSString* executablePath =
121 [NSBundle bundleWithPath:applicationFrameworkPath].executablePath;
122 if (executablePath.length > 0) {
123 settings.application_library_paths.push_back(executablePath.UTF8String);
124 }
125 }
126 }
127 }
128
129 // Checks to see if the flutter assets directory is already present.
130 if (settings.assets_path.empty()) {
131 NSString* assetsPath = FLTAssetsPathFromBundle(bundle);
132
133 if (assetsPath.length == 0) {
134 NSLog(@"Failed to find assets path for \"%@\"", bundle);
135 } else {
136 settings.assets_path = assetsPath.UTF8String;
137
138 // Check if there is an application kernel snapshot in the assets directory we could
139 // potentially use. Looking for the snapshot makes sense only if we have a VM that can use
140 // it.
142 NSURL* applicationKernelSnapshotURL =
143 [NSURL URLWithString:@(kApplicationKernelSnapshotFileName)
144 relativeToURL:[NSURL fileURLWithPath:assetsPath]];
145 NSError* error;
146 if ([applicationKernelSnapshotURL checkResourceIsReachableAndReturnError:&error]) {
147 settings.application_kernel_asset = applicationKernelSnapshotURL.path.UTF8String;
148 } else {
149 NSLog(@"Failed to find snapshot at %@: %@", applicationKernelSnapshotURL.path, error);
150 }
151 }
152 }
153 }
154
155 // Domain network configuration
156 // Disabled in https://github.com/flutter/flutter/issues/72723.
157 // Re-enable in https://github.com/flutter/flutter/issues/54448.
158 settings.may_insecurely_connect_to_all_domains = true;
159 settings.domain_network_policy = "";
160
161 // Whether to enable wide gamut colors.
162#if TARGET_OS_SIMULATOR
163 // As of Xcode 14.1, the wide gamut surface pixel formats are not supported by
164 // the simulator.
165 settings.enable_wide_gamut = false;
166 // Removes unused function warning.
168#else
169 NSNumber* nsEnableWideGamut = [mainBundle objectForInfoDictionaryKey:@"FLTEnableWideGamut"];
170 BOOL enableWideGamut =
171 (nsEnableWideGamut ? nsEnableWideGamut.boolValue : YES) && DoesHardwareSupportWideGamut();
172 settings.enable_wide_gamut = enableWideGamut;
173#endif
174
175 NSNumber* nsAntialiasLines = [mainBundle objectForInfoDictionaryKey:@"FLTAntialiasLines"];
176 settings.impeller_antialiased_lines = (nsAntialiasLines ? nsAntialiasLines.boolValue : NO);
177
178 settings.warn_on_impeller_opt_out = true;
179
180 NSNumber* nsEnableSDFs = [mainBundle objectForInfoDictionaryKey:@"FLTEnableSDFs"];
181 settings.impeller_use_sdfs = (nsEnableSDFs ? nsEnableSDFs.boolValue : NO);
182
183 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"];
184 // Change the default only if the option is present.
185 if (enableTraceSystrace != nil) {
186 settings.trace_systrace = enableTraceSystrace.boolValue;
187 }
188
189 NSNumber* profileMicrotasks = [mainBundle objectForInfoDictionaryKey:@"FLTProfileMicrotasks"];
190 // Change the default only if the option is present.
191 if (profileMicrotasks != nil) {
192 settings.profile_microtasks = profileMicrotasks.boolValue;
193 }
194
195 NSNumber* enableDartAsserts = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartAsserts"];
196 if (enableDartAsserts != nil) {
197 settings.dart_flags.push_back("--enable-asserts");
198 }
199
200 NSNumber* enableDartProfiling = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartProfiling"];
201 // Change the default only if the option is present.
202 if (enableDartProfiling != nil) {
203 settings.enable_dart_profiling = enableDartProfiling.boolValue;
204 }
205
206 NSNumber* profileStartup = [mainBundle objectForInfoDictionaryKey:@"FLTProfileStartup"];
207 // Change the default only if the option is present.
208 if (profileStartup != nil) {
209 settings.profile_startup = profileStartup.boolValue;
210 }
211
212 // Leak Dart VM settings, set whether leave or clean up the VM after the last shell shuts down.
213 NSNumber* leakDartVM = [mainBundle objectForInfoDictionaryKey:@"FLTLeakDartVM"];
214 // It will change the default leak_vm value in settings only if the key exists.
215 if (leakDartVM != nil) {
216 settings.leak_vm = leakDartVM.boolValue;
217 }
218
219 NSNumber* enableMergedPlatformUIThread =
220 [mainBundle objectForInfoDictionaryKey:@"FLTEnableMergedPlatformUIThread"];
221 if (enableMergedPlatformUIThread != nil) {
222 FML_CHECK(enableMergedPlatformUIThread.boolValue)
223 << "FLTEnableMergedPlatformUIThread=false is no longer allowed.";
224 }
225
226 NSNumber* enableFlutterGPU = [mainBundle objectForInfoDictionaryKey:@"FLTEnableFlutterGPU"];
227 if (enableFlutterGPU != nil) {
228 settings.enable_flutter_gpu = enableFlutterGPU.boolValue;
229 }
230
231#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
232 // There are no ownership concerns here as all mappings are owned by the
233 // embedder and not the engine.
234 auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
235 return [mapping, size]() { return std::make_unique<fml::NonOwnedMapping>(mapping, size); };
236 };
237
238 settings.dart_library_sources_kernel =
239 make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
240#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
241
242 // If we even support setting this e.g. from the command line or the plist,
243 // we should let the user override it.
244 // Otherwise, we want to set this to a value that will avoid having the OS
245 // kill us. On most iOS devices, that happens somewhere near half
246 // the available memory.
247 // The VM expects this value to be in megabytes.
248 if (settings.old_gen_heap_size <= 0) {
249 settings.old_gen_heap_size = std::round([NSProcessInfo processInfo].physicalMemory * .48 /
251 }
252
253 // This is the formula Android uses.
254 // https://android.googlesource.com/platform/frameworks/base/+/39ae5bac216757bc201490f4c7b8c0f63006c6cd/libs/hwui/renderthread/CacheManager.cpp#45
255 CGFloat scale = [UIScreen mainScreen].scale;
256 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width * scale;
257 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height * scale;
258 settings.resource_cache_max_bytes_threshold = screenWidth * screenHeight * 12 * 4;
259
260 // Whether to enable ios embedder api.
261 NSNumber* enable_embedder_api =
262 [mainBundle objectForInfoDictionaryKey:@"FLTEnableIOSEmbedderAPI"];
263 // Change the default only if the option is present.
264 if (enable_embedder_api) {
265 settings.enable_embedder_api = enable_embedder_api.boolValue;
266 }
267
268 return settings;
269}
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
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

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