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