| Flutter macOS Embedder |

FlutterDartProject.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h"
6 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
7
8 #include <vector>
9
10 #import <Metal/Metal.h>
11
12 #include "flutter/shell/platform/common/engine_switches.h"
13
14 static NSString* const kICUBundlePath = @"icudtl.dat";
15
16 static BOOL DoesHardwareSupportWideGamut() {
17 static BOOL result = NO;
18 static dispatch_once_t once_token = 0;
19 dispatch_once(&once_token, ^{
20 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
21 // Wide gamut on macOS requires Apple3+ GPU family (Apple Silicon M1+).
22 // This uses 10-bit BGRA format (same as iOS) for consistency.
23 // Intel Macs (Mac1/Mac2 family) do not support wide gamut.
24 result = [device supportsFamily:MTLGPUFamilyApple3];
25 });
26 return result;
27 }
28 static NSString* const kAppBundleIdentifier = @"io.flutter.flutter.app";
29
30 #pragma mark - Private interface declaration.
31 @interface FlutterDartProject ()
32 /**
33 Get the Flutter assets name path by pass the bundle. If bundle is nil, we use the main bundle as
34 default.
35 */
36 + (NSString*)flutterAssetsNameWithBundle:(NSBundle*)bundle;
37 @end
38
39 @implementation FlutterDartProject {
40 NSBundle* _dartBundle;
41 NSString* _assetsPath;
42 NSString* _ICUDataPath;
43 }
44
45 - (instancetype)init {
46 return [self initWithPrecompiledDartBundle:nil];
47 }
48
49 - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle {
50 self = [super init];
51 NSAssert(self, @"Super init cannot be nil");
52
53 _dartBundle = bundle ?: FLTFrameworkBundleWithIdentifier(kAppBundleIdentifier);
54 if (_dartBundle == nil) {
55 // The bundle isn't loaded and can't be found by bundle ID. Find it by path.
56 _dartBundle = [NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL
57 URLByAppendingPathComponent:@"App.framework"]];
58 }
59 if (!_dartBundle.isLoaded) {
60 [_dartBundle load];
61 }
62 _dartEntrypointArguments = [[NSProcessInfo processInfo] arguments];
63 // Remove the first element as it's the binary name
64 _dartEntrypointArguments = [_dartEntrypointArguments
65 subarrayWithRange:NSMakeRange(1, _dartEntrypointArguments.count - 1)];
66 return self;
67 }
68
69 - (instancetype)initWithAssetsPath:(NSString*)assets ICUDataPath:(NSString*)icuPath {
70 self = [super init];
71 NSAssert(self, @"Super init cannot be nil");
72 _assetsPath = assets;
73 _ICUDataPath = icuPath;
74 return self;
75 }
76
77 - (BOOL)enableImpeller {
78 NSNumber* enableImpeller =
79 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableImpeller"];
80 if (enableImpeller != nil) {
81 return enableImpeller.boolValue;
82 }
83 return NO;
84 }
85
86 - (BOOL)enableWideGamut {
87 NSNumber* enableWideGamut =
88 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableWideGamut"];
89 if (enableWideGamut != nil) {
90 return enableWideGamut.boolValue && DoesHardwareSupportWideGamut();
91 }
92 return NO;
93 }
94
95 - (BOOL)enableFlutterGPU {
96 NSNumber* enableFlutterGPU =
97 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableFlutterGPU"];
98 if (enableFlutterGPU != nil) {
99 return enableFlutterGPU.boolValue;
100 }
101 return NO;
102 }
103
104 - (BOOL)enableSDFs {
105 NSNumber* enableSDFs = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableSDFs"];
106 if (enableSDFs != nil) {
107 return enableSDFs.boolValue;
108 }
109 return NO;
110 }
111
112 - (NSString*)assetsPath {
113 if (_assetsPath) {
114 return _assetsPath;
115 }
116
117 // If there's no App.framework, fall back to checking the main bundle for assets.
118 NSBundle* assetBundle = _dartBundle ?: [NSBundle mainBundle];
119 NSString* flutterAssetsName = [assetBundle objectForInfoDictionaryKey:@"FLTAssetsPath"];
120 if (flutterAssetsName == nil) {
121 flutterAssetsName = @"flutter_assets";
122 }
123 NSString* path = [assetBundle pathForResource:flutterAssetsName ofType:@""];
124 if (!path) {
125 NSLog(@"Failed to find path for \"%@\"", flutterAssetsName);
126 }
127 return path;
128 }
129
130 - (NSString*)ICUDataPath {
131 if (_ICUDataPath) {
132 return _ICUDataPath;
133 }
134
135 NSString* path = [[NSBundle bundleForClass:[self class]] pathForResource:kICUBundlePath
136 ofType:nil];
137 if (!path) {
138 NSLog(@"Failed to find path for \"%@\"", kICUBundlePath);
139 }
140 return path;
141 }
142
143 + (NSString*)flutterAssetsNameWithBundle:(NSBundle*)bundle {
144 if (bundle == nil) {
145 bundle = FLTFrameworkBundleWithIdentifier(kAppBundleIdentifier);
146 }
147 if (bundle == nil) {
148 bundle = [NSBundle mainBundle];
149 }
150 NSString* flutterAssetsName = [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"];
151 if (flutterAssetsName == nil) {
152 flutterAssetsName = @"Contents/Frameworks/App.framework/Resources/flutter_assets";
153 }
154 return flutterAssetsName;
155 }
156
157 + (NSString*)lookupKeyForAsset:(NSString*)asset {
158 return [self lookupKeyForAsset:asset fromBundle:nil];
159 }
160
161 + (NSString*)lookupKeyForAsset:(NSString*)asset fromBundle:(nullable NSBundle*)bundle {
162 NSString* flutterAssetsName = [FlutterDartProject flutterAssetsNameWithBundle:bundle];
163 return [NSString stringWithFormat:@"%@/%@", flutterAssetsName, asset];
164 }
165
166 + (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
167 return [self lookupKeyForAsset:asset fromPackage:package fromBundle:nil];
168 }
169
170 + (NSString*)lookupKeyForAsset:(NSString*)asset
171 fromPackage:(NSString*)package
172 fromBundle:(nullable NSBundle*)bundle {
173 return [self lookupKeyForAsset:[NSString stringWithFormat:@"packages/%@/%@", package, asset]
174 fromBundle:bundle];
175 }
176
177 + (NSString*)defaultBundleIdentifier {
178 return kAppBundleIdentifier;
179 }
180
181 @end
FlutterDartProject.h
kAppBundleIdentifier
static NSString *const kAppBundleIdentifier
Definition: FlutterDartProject.mm:28
kICUBundlePath
static NSString *const kICUBundlePath
Definition: FlutterDartProject.mm:14
_ICUDataPath
NSString * _ICUDataPath
Definition: FlutterDartProject.mm:42
_assetsPath
NSString * _assetsPath
Definition: FlutterDartProject.mm:39
DoesHardwareSupportWideGamut
static BOOL DoesHardwareSupportWideGamut()
Definition: FlutterDartProject.mm:16
FlutterDartProject_Internal.h
FLTFrameworkBundleWithIdentifier
NSBundle * FLTFrameworkBundleWithIdentifier(NSString *flutterFrameworkBundleID)
Definition: FlutterNSBundleUtils.mm:46
FlutterDartProject
Definition: FlutterDartProject.mm:39
engine_switches.h