Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Macros | Functions | Variables
FlutterDartProject.mm File Reference
import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
#include <syslog.h>
import <Metal/Metal.h>
#include <sstream>
#include <string>
#include "flutter/common/constants.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
import "flutter/shell/platform/darwin/common/command_line.h"
import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.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_NOT_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 38 of file FlutterDartProject.mm.

38 {
39 static BOOL result = NO;
40 static dispatch_once_t once_token = 0;
41 dispatch_once(&once_token, ^{
42 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
43 if (@available(iOS 13.0, *)) {
44 // MTLGPUFamilyApple2 = A9/A10
45 result = [device supportsFamily:MTLGPUFamilyApple2];
46 } else {
47 // A9/A10 on iOS 10+
48 result = [device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2];
49 }
50 [device release];
51 });
52 return result;
53}
VkDevice device
Definition main.cc:53
GAsyncResult * result
int BOOL

◆ FLTDefaultSettingsForBundle()

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

Definition at line 55 of file FlutterDartProject.mm.

55 {
56 auto command_line = flutter::CommandLineFromNSProcessInfo(processInfoOrNil);
57
58 // Precedence:
59 // 1. Settings from the specified NSBundle (except for enable-impeller).
60 // 2. Settings passed explicitly via command-line arguments.
61 // 3. Settings from the NSBundle with the default bundle ID.
62 // 4. Settings from the main NSBundle and default values.
63
64 NSBundle* mainBundle = FLTGetApplicationBundle();
65 NSBundle* engineBundle = [NSBundle bundleForClass:[FlutterViewController class]];
66
67 bool hasExplicitBundle = bundle != nil;
68 if (bundle == nil) {
69 bundle = FLTFrameworkBundleWithIdentifier([FlutterDartProject defaultBundleIdentifier]);
70 }
71
72 auto settings = flutter::SettingsFromCommandLine(command_line);
73
74 settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
76 };
77
78 settings.task_observer_remove = [](intptr_t key) {
80 };
81
82 settings.log_message_callback = [](const std::string& tag, const std::string& message) {
83 // TODO(cbracken): replace this with os_log-based approach.
84 // https://github.com/flutter/flutter/issues/44030
85 std::stringstream stream;
86 if (!tag.empty()) {
87 stream << tag << ": ";
88 }
89 stream << message;
90 std::string log = stream.str();
91 syslog(LOG_ALERT, "%.*s", (int)log.size(), log.c_str());
92 };
93
94 settings.enable_platform_isolates = true;
95
96 // The command line arguments may not always be complete. If they aren't, attempt to fill in
97 // defaults.
98
99 // Flutter ships the ICU data file in the bundle of the engine. Look for it there.
100 if (settings.icu_data_path.empty()) {
101 NSString* icuDataPath = [engineBundle pathForResource:@"icudtl" ofType:@"dat"];
102 if (icuDataPath.length > 0) {
103 settings.icu_data_path = icuDataPath.UTF8String;
104 }
105 }
106
108 if (hasExplicitBundle) {
109 NSString* executablePath = bundle.executablePath;
110 if ([[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
111 settings.application_library_path.push_back(executablePath.UTF8String);
112 }
113 }
114
115 // No application bundle specified. Try a known location from the main bundle's Info.plist.
116 if (settings.application_library_path.empty()) {
117 NSString* libraryName = [mainBundle objectForInfoDictionaryKey:@"FLTLibraryPath"];
118 NSString* libraryPath = [mainBundle pathForResource:libraryName ofType:@""];
119 if (libraryPath.length > 0) {
120 NSString* executablePath = [NSBundle bundleWithPath:libraryPath].executablePath;
121 if (executablePath.length > 0) {
122 settings.application_library_path.push_back(executablePath.UTF8String);
123 }
124 }
125 }
126
127 // In case the application bundle is still not specified, look for the App.framework in the
128 // Frameworks directory.
129 if (settings.application_library_path.empty()) {
130 NSString* applicationFrameworkPath = [mainBundle pathForResource:@"Frameworks/App.framework"
131 ofType:@""];
132 if (applicationFrameworkPath.length > 0) {
133 NSString* executablePath =
134 [NSBundle bundleWithPath:applicationFrameworkPath].executablePath;
135 if (executablePath.length > 0) {
136 settings.application_library_path.push_back(executablePath.UTF8String);
137 }
138 }
139 }
140 }
141
142 // Checks to see if the flutter assets directory is already present.
143 if (settings.assets_path.empty()) {
144 NSString* assetsPath = FLTAssetsPathFromBundle(bundle);
145
146 if (assetsPath.length == 0) {
147 NSLog(@"Failed to find assets path for \"%@\"", bundle);
148 } else {
149 settings.assets_path = assetsPath.UTF8String;
150
151 // Check if there is an application kernel snapshot in the assets directory we could
152 // potentially use. Looking for the snapshot makes sense only if we have a VM that can use
153 // it.
155 NSURL* applicationKernelSnapshotURL =
156 [NSURL URLWithString:@(kApplicationKernelSnapshotFileName)
157 relativeToURL:[NSURL fileURLWithPath:assetsPath]];
158 NSError* error;
159 if ([applicationKernelSnapshotURL checkResourceIsReachableAndReturnError:&error]) {
160 settings.application_kernel_asset = applicationKernelSnapshotURL.path.UTF8String;
161 } else {
162 NSLog(@"Failed to find snapshot at %@: %@", applicationKernelSnapshotURL.path, error);
163 }
164 }
165 }
166 }
167
168 // Domain network configuration
169 // Disabled in https://github.com/flutter/flutter/issues/72723.
170 // Re-enable in https://github.com/flutter/flutter/issues/54448.
171 settings.may_insecurely_connect_to_all_domains = true;
172 settings.domain_network_policy = "";
173
174 // Whether to enable wide gamut colors.
175#if TARGET_OS_SIMULATOR
176 // As of Xcode 14.1, the wide gamut surface pixel formats are not supported by
177 // the simulator.
178 settings.enable_wide_gamut = false;
179 // Removes unused function warning.
181#else
182 NSNumber* nsEnableWideGamut = [mainBundle objectForInfoDictionaryKey:@"FLTEnableWideGamut"];
183 BOOL enableWideGamut =
184 (nsEnableWideGamut ? nsEnableWideGamut.boolValue : YES) && DoesHardwareSupportWideGamut();
185 settings.enable_wide_gamut = enableWideGamut;
186#endif
187
188 // TODO(dnfield): We should reverse the order for all these settings so that command line options
189 // are preferred to plist settings. https://github.com/flutter/flutter/issues/124049
190 // Whether to enable Impeller. If the command line explicitly
191 // specified an option for this, ignore what's in the plist.
192 if (!command_line.HasOption("enable-impeller")) {
193 // Next, look in the app bundle.
194 NSNumber* enableImpeller = [bundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
195 if (enableImpeller == nil) {
196 // If it isn't in the app bundle, look in the main bundle.
197 enableImpeller = [mainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"];
198 }
199 // Change the default only if the option is present.
200 if (enableImpeller != nil) {
201 settings.enable_impeller = enableImpeller.boolValue;
202 }
203 }
204
205 settings.warn_on_impeller_opt_out = true;
206
207 NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"];
208 // Change the default only if the option is present.
209 if (enableTraceSystrace != nil) {
210 settings.trace_systrace = enableTraceSystrace.boolValue;
211 }
212
213 NSNumber* enableDartAsserts = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartAsserts"];
214 if (enableDartAsserts != nil) {
215 settings.dart_flags.push_back("--enable-asserts");
216 }
217
218 NSNumber* enableDartProfiling = [mainBundle objectForInfoDictionaryKey:@"FLTEnableDartProfiling"];
219 // Change the default only if the option is present.
220 if (enableDartProfiling != nil) {
221 settings.enable_dart_profiling = enableDartProfiling.boolValue;
222 }
223
224 // Leak Dart VM settings, set whether leave or clean up the VM after the last shell shuts down.
225 NSNumber* leakDartVM = [mainBundle objectForInfoDictionaryKey:@"FLTLeakDartVM"];
226 // It will change the default leak_vm value in settings only if the key exists.
227 if (leakDartVM != nil) {
228 settings.leak_vm = leakDartVM.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:205
void RemoveTaskObserver(intptr_t key)
void AddTaskObserver(intptr_t key, const fml::closure &callback)
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
FLUTTER_ASSERT_NOT_ARC const uint8_t kPlatformStrongDill[]
static const char * kApplicationKernelSnapshotFileName
const intptr_t kPlatformStrongDillSize
static BOOL DoesHardwareSupportWideGamut()
Win32Message message
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
Definition switches.cc:228
fml::CommandLine CommandLineFromNSProcessInfo(NSProcessInfo *processInfoOrNil=nil)
constexpr double kMegaByteSizeInBytes
Definition constants.h:9
it will be possible to load the file into Perfetto s trace viewer 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
Definition switches.h:259
std::function< void()> closure
Definition closure.h:14
const Scalar scale

Variable Documentation

◆ kApplicationKernelSnapshotFileName

const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin"
static

Definition at line 36 of file FlutterDartProject.mm.

◆ kPlatformStrongDill

FLUTTER_ASSERT_NOT_ARC const uint8_t kPlatformStrongDill[]
extern

◆ kPlatformStrongDillSize

const intptr_t kPlatformStrongDillSize
extern