diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 61cb7b1a2d696..8f80d70a8ab5f 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2458,11 +2458,14 @@ ORIGIN: ../../../flutter/shell/platform/darwin/common/command_line.mm + ../../.. ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannels.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.h + ../../../flutter/LICENSE @@ -2476,7 +2479,6 @@ ORIGIN: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTex ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngineGroup.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h + ../../../flutter/LICENSE @@ -2612,7 +2614,6 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.mm + ../../ ORIGIN: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterMacOS.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterPlatformViews.h + ../../../flutter/LICENSE @@ -5057,11 +5058,14 @@ FILE: ../../../flutter/shell/platform/darwin/common/command_line.mm FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h +FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannels.mm FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm +FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h +FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.cc FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.h @@ -5075,7 +5079,6 @@ FILE: ../../../flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextu FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/Flutter.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h -FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngineGroup.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadlessDartRunner.h @@ -5213,7 +5216,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.mm FILE: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.h FILE: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h -FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterMacOS.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterPlatformViews.h diff --git a/shell/platform/darwin/common/BUILD.gn b/shell/platform/darwin/common/BUILD.gn index a3210bfed4d25..d7c0a0cf17be6 100644 --- a/shell/platform/darwin/common/BUILD.gn +++ b/shell/platform/darwin/common/BUILD.gn @@ -36,6 +36,8 @@ source_set("framework_shared") { sources = [ "framework/Source/FlutterChannels.mm", "framework/Source/FlutterCodecs.mm", + "framework/Source/FlutterNSBundleUtils.h", + "framework/Source/FlutterNSBundleUtils.mm", "framework/Source/FlutterStandardCodec.mm", "framework/Source/FlutterStandardCodecHelper.cc", "framework/Source/FlutterStandardCodec_Internal.h", @@ -43,6 +45,8 @@ source_set("framework_shared") { public = framework_shared_headers + public += [ "framework/Source/FlutterNSBundleUtils.h" ] + defines = [ "FLUTTER_FRAMEWORK" ] public_configs = [ diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h b/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h similarity index 75% rename from shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h rename to shell/platform/darwin/common/framework/Headers/FlutterDartProject.h index 8f64d124a69f3..2878a1d202e57 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h @@ -6,6 +6,7 @@ #define FLUTTER_FLUTTERDARTPROJECT_H_ #import +#import #import "FlutterMacros.h" @@ -13,25 +14,49 @@ NS_ASSUME_NONNULL_BEGIN /** * A set of Flutter and Dart assets used by a `FlutterEngine` to initialize execution. + * */ FLUTTER_DARWIN_EXPORT @interface FlutterDartProject : NSObject /** * Initializes a Flutter Dart project from a bundle. + * + * The bundle must either contain a flutter_assets resource directory, or set the Info.plist key + * FLTAssetsPath to override that name (if you are doing a custom build using a different name). + * + * @param bundle The bundle containing the Flutter assets directory. If nil, the App framework + * created by Flutter will be used. */ - (instancetype)initWithPrecompiledDartBundle:(nullable NSBundle*)bundle NS_DESIGNATED_INITIALIZER; - /** * Unavailable - use `init` instead. */ -- (instancetype)initFromDefaultSourceForConfiguration FLUTTER_UNAVAILABLE("Use -init instead."); +- (instancetype)initFromDefaultSourceForConfiguration API_UNAVAILABLE(macos) + FLUTTER_UNAVAILABLE("Use -init instead."); + +/** + * Returns the default identifier for the bundle where we expect to find the Flutter Dart + * application. + */ ++ (NSString*)defaultBundleIdentifier; + +/** + * An NSArray of NSStrings to be passed as command line arguments to the Dart entrypoint. + * + * If this is not explicitly set, this will default to the contents of + * [NSProcessInfo arguments], without the binary name. + * + * Set this to nil to pass no arguments to the Dart entrypoint. + */ +@property(nonatomic, nullable, copy) + NSArray* dartEntrypointArguments API_UNAVAILABLE(ios); /** * Returns the file name for the given asset. If the bundle with the identifier * "io.flutter.flutter.app" exists, it will try use that bundle; otherwise, it * will use the main bundle. To specify a different bundle, use - * `-lookupKeyForAsset:asset:fromBundle`. + * `+lookupKeyForAsset:fromBundle`. * * @param asset The name of the asset. The name can be hierarchical. * @return the file name to be used for lookup in the main bundle. @@ -71,12 +96,6 @@ FLUTTER_DARWIN_EXPORT fromPackage:(NSString*)package fromBundle:(nullable NSBundle*)bundle; -/** - * Returns the default identifier for the bundle where we expect to find the Flutter Dart - * application. - */ -+ (NSString*)defaultBundleIdentifier; - @end NS_ASSUME_NONNULL_END diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h new file mode 100644 index 0000000000000..569b551cfa951 --- /dev/null +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_PLATFORM_DARWIN_COMMON_FRAMEWORK_SOURCE_FLUTTERNSBUNDLEUTILS_H_ +#define SHELL_PLATFORM_DARWIN_COMMON_FRAMEWORK_SOURCE_FLUTTERNSBUNDLEUTILS_H_ + +#import + +NS_ASSUME_NONNULL_BEGIN + +// Finds a bundle with the named `bundleID` within `searchURL`. +// +// Returns `nil` if the bundle cannot be found or if errors are encountered. +NSBundle* FLTFrameworkBundleInternal(NSString* bundleID, NSURL* searchURL); + +// Finds a bundle with the named `bundleID`. +// +// `+[NSBundle bundleWithIdentifier:]` is slow, and can take in the order of +// tens of milliseconds in a minimal flutter app, and closer to 100 milliseconds +// in a medium sized Flutter app on an iPhone 13. It is likely that the slowness +// comes from having to traverse and load all bundles known to the process. +// Using `+[NSBundle allframeworks]` and filtering also suffers from the same +// problem. +// +// This implementation is an optimization to first limit the search space to +// `+[NSBundle privateFrameworksURL]` of the main bundle, which is usually where +// frameworks used by this file are placed. If the desired bundle cannot be +// found here, the implementation falls back to +// `+[NSBundle bundleWithIdentifier:]`. +NSBundle* FLTFrameworkBundleWithIdentifier(NSString* bundleID); + +NS_ASSUME_NONNULL_END + +#endif // SHELL_PLATFORM_DARWIN_COMMON_FRAMEWORK_SOURCE_FLUTTERNSBUNDLEUTILS_H_ diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm new file mode 100644 index 0000000000000..7ad26579f511c --- /dev/null +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +NSBundle* FLTFrameworkBundleInternal(NSString* bundleID, NSURL* searchURL) { + NSDirectoryEnumerator* frameworkEnumerator = [NSFileManager.defaultManager + enumeratorAtURL:searchURL + includingPropertiesForKeys:nil + options:NSDirectoryEnumerationSkipsSubdirectoryDescendants | + NSDirectoryEnumerationSkipsHiddenFiles + // Skip directories where errors are encountered. + errorHandler:nil]; + + for (NSURL* candidate in frameworkEnumerator) { + NSBundle* bundle = [NSBundle bundleWithURL:candidate]; + if ([bundle.bundleIdentifier isEqualToString:bundleID]) { + return bundle; + } + } + return nil; +} + +NSBundle* FLTFrameworkBundleWithIdentifier(NSString* bundleID) { + NSBundle* bundle = FLTFrameworkBundleInternal(bundleID, NSBundle.mainBundle.privateFrameworksURL); + if (bundle != nil) { + return bundle; + } + // Fallback to slow implementation. + return [NSBundle bundleWithIdentifier:bundleID]; +} diff --git a/shell/platform/darwin/common/framework_shared.gni b/shell/platform/darwin/common/framework_shared.gni index 8a679c4d6fa25..84f50a7da548e 100644 --- a/shell/platform/darwin/common/framework_shared.gni +++ b/shell/platform/darwin/common/framework_shared.gni @@ -9,5 +9,6 @@ framework_shared_headers = "framework/Headers/FlutterChannels.h", "framework/Headers/FlutterCodecs.h", "framework/Headers/FlutterTexture.h", + "framework/Headers/FlutterDartProject.h", ], "abspath") diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 7a30a1fb16d03..4acf7e2bcf062 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -27,7 +27,6 @@ _flutter_framework_headers = [ "framework/Headers/Flutter.h", "framework/Headers/FlutterAppDelegate.h", "framework/Headers/FlutterCallbackCache.h", - "framework/Headers/FlutterDartProject.h", "framework/Headers/FlutterEngine.h", "framework/Headers/FlutterEngineGroup.h", "framework/Headers/FlutterHeadlessDartRunner.h", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index a9bbe4fa7bda9..a61ab0568795f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -32,50 +32,6 @@ static const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin"; -// Finds a bundle with the named `bundleID` within `searchURL`. -// -// Returns `nil` if the bundle cannot be found or if errors are encountered. -NSBundle* FLTFrameworkBundleInternal(NSString* bundleID, NSURL* searchURL) { - NSDirectoryEnumerator* frameworkEnumerator = [NSFileManager.defaultManager - enumeratorAtURL:searchURL - includingPropertiesForKeys:nil - options:NSDirectoryEnumerationSkipsSubdirectoryDescendants | - NSDirectoryEnumerationSkipsHiddenFiles - // Skip directories where errors are encountered. - errorHandler:nil]; - - for (NSURL* candidate in frameworkEnumerator) { - NSBundle* bundle = [NSBundle bundleWithURL:candidate]; - if ([bundle.bundleIdentifier isEqualToString:bundleID]) { - return bundle; - } - } - return nil; -} - -// Finds a bundle with the named `bundleID`. -// -// `+[NSBundle bundleWithIdentifier:]` is slow, and can take in the order of -// tens of milliseconds in a minimal flutter app, and closer to 100 milliseconds -// in a medium sized Flutter app on an iPhone 13. It is likely that the slowness -// comes from having to traverse and load all bundles known to the process. -// Using `+[NSBundle allframeworks]` and filtering also suffers from the same -// problem. -// -// This implementation is an optimization to first limit the search space to -// `+[NSBundle privateFrameworksURL]` of the main bundle, which is usually where -// frameworks used by this file are placed. If the desired bundle cannot be -// found here, the implementation falls back to -// `+[NSBundle bundleWithIdentifier:]`. -NS_INLINE NSBundle* FLTFrameworkBundleWithIdentifier(NSString* bundleID) { - NSBundle* bundle = FLTFrameworkBundleInternal(bundleID, NSBundle.mainBundle.privateFrameworksURL); - if (bundle != nil) { - return bundle; - } - // Fallback to slow implementation. - return [NSBundle bundleWithIdentifier:bundleID]; -} - flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle, NSProcessInfo* processInfoOrNil) { auto command_line = flutter::CommandLineFromNSProcessInfo(processInfoOrNil); @@ -286,6 +242,11 @@ @implementation FlutterDartProject { flutter::Settings _settings; } +// This property is marked unavailable on iOS in the common header. +// That doesn't seem to be enough to prevent this property from being synthesized. +// Mark dynamic to avoid warnings. +@dynamic dartEntrypointArguments; + #pragma mark - Override base class designated initializers - (instancetype)init { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h index 3888a785eb421..8ca970a337f7c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h @@ -8,12 +8,11 @@ #include "flutter/common/settings.h" #include "flutter/runtime/platform_data.h" #include "flutter/shell/common/engine.h" -#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h" +#import "flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h" NS_ASSUME_NONNULL_BEGIN -NSBundle* FLTFrameworkBundleInternal(NSString* bundleID, NSURL* searchURL); - flutter::Settings FLTDefaultSettingsForBundle(NSBundle* _Nullable bundle = nil, NSProcessInfo* _Nullable processInfoOrNil = nil); diff --git a/shell/platform/darwin/macos/BUILD.gn b/shell/platform/darwin/macos/BUILD.gn index 3e38ac0d910b1..da8152cd86497 100644 --- a/shell/platform/darwin/macos/BUILD.gn +++ b/shell/platform/darwin/macos/BUILD.gn @@ -38,7 +38,6 @@ _framework_binary_subpath = "Versions/A/$_flutter_framework_name" # the Flutter engine source root. _flutter_framework_headers = [ "framework/Headers/FlutterAppDelegate.h", - "framework/Headers/FlutterDartProject.h", "framework/Headers/FlutterEngine.h", "framework/Headers/FlutterMacOS.h", "framework/Headers/FlutterPlatformViews.h", diff --git a/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h b/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h deleted file mode 100644 index a31d733631840..0000000000000 --- a/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_FLUTTERDARTPROJECT_H_ -#define FLUTTER_FLUTTERDARTPROJECT_H_ - -#import - -#import "FlutterMacros.h" - -/** - * A set of Flutter and Dart assets used by a `FlutterEngine` to initialize execution. - * - * TODO(stuartmorgan): Align API with FlutterDartProject, and combine. - */ -FLUTTER_DARWIN_EXPORT -@interface FlutterDartProject : NSObject - -/** - * Initializes a Flutter Dart project from a bundle. - * - * The bundle must either contain a flutter_assets resource directory, or set the Info.plist key - * FLTAssetsPath to override that name (if you are doing a custom build using a different name). - * - * @param bundle The bundle containing the Flutter assets directory. If nil, the App framework - * created by Flutter will be used. - */ -- (nonnull instancetype)initWithPrecompiledDartBundle:(nullable NSBundle*)bundle - NS_DESIGNATED_INITIALIZER; - -/** - * An NSArray of NSStrings to be passed as command line arguments to the Dart entrypoint. - * - * If this is not explicitly set, this will default to the contents of - * [NSProcessInfo arguments], without the binary name. - * - * Set this to nil to pass no arguments to the Dart entrypoint. - */ -@property(nonatomic, nullable, copy) NSArray* dartEntrypointArguments; - -@end - -#endif // FLUTTER_FLUTTERDARTPROJECT_H_ diff --git a/shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h b/shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h index 39fbba1b43bd3..67a843474bea2 100644 --- a/shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h +++ b/shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h @@ -67,6 +67,27 @@ FLUTTER_DARWIN_EXPORT - (void)registerViewFactory:(nonnull NSObject*)factory withId:(nonnull NSString*)factoryId; +/** + * Returns the file name for the given asset. + * The returned file name can be used to access the asset in the application's main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @return the file name to be used for lookup in the main bundle. + */ +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset; + +/** + * Returns the file name for the given asset which originates from the specified package. + * The returned file name can be used to access the asset in the application's main bundle. + * + * + * @param asset The name of the asset. The name can be hierarchical. + * @param package The name of the package from which the asset originates. + * @return the file name to be used for lookup in the main bundle. + */ +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset + fromPackage:(nonnull NSString*)package; + @end /** diff --git a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h index eb3c0a0f5984a..401a6ae5ebbfa 100644 --- a/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h @@ -117,6 +117,29 @@ FLUTTER_DARWIN_EXPORT */ - (void)onPreEngineRestart; +/** + * Returns the file name for the given asset. + * The returned file name can be used to access the asset in the application's + * main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @return The file name to be used for lookup in the main bundle. + */ +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset; + +/** + * Returns the file name for the given asset which originates from the specified + * package. + * The returned file name can be used to access the asset in the application's + * main bundle. + * + * @param asset The name of the asset. The name can be hierarchical. + * @param package The name of the package from which the asset originates. + * @return The file name to be used for lookup in the main bundle. + */ +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset + fromPackage:(nonnull NSString*)package; + /** * The contentView (FlutterView)'s background color is set to black during * its instantiation. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/macos/framework/Source/FlutterDartProject.mm index 80bed03f072b4..8391e4f8b4550 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterDartProject.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h" #include @@ -12,6 +12,15 @@ static NSString* const kICUBundlePath = @"icudtl.dat"; static NSString* const kAppBundleIdentifier = @"io.flutter.flutter.app"; +#pragma mark - Private interface declaration. +@interface FlutterDartProject () +/** + Get the Flutter assets name path by pass the bundle. If bundle is nil, we use the main bundle as + default. + */ ++ (NSString*)flutterAssetsNameWithBundle:(NSBundle*)bundle; +@end + @implementation FlutterDartProject { NSBundle* _dartBundle; NSString* _assetsPath; @@ -26,7 +35,7 @@ - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _dartBundle = bundle ?: [NSBundle bundleWithIdentifier:kAppBundleIdentifier]; + _dartBundle = bundle ?: FLTFrameworkBundleWithIdentifier(kAppBundleIdentifier); if (_dartBundle == nil) { // The bundle isn't loaded and can't be found by bundle ID. Find it by path. _dartBundle = [NSBundle bundleWithURL:[NSBundle.mainBundle.privateFrameworksURL @@ -81,4 +90,42 @@ - (NSString*)ICUDataPath { return path; } ++ (NSString*)flutterAssetsNameWithBundle:(NSBundle*)bundle { + if (bundle == nil) { + bundle = FLTFrameworkBundleWithIdentifier(kAppBundleIdentifier); + } + if (bundle == nil) { + bundle = [NSBundle mainBundle]; + } + NSString* flutterAssetsName = [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"]; + if (flutterAssetsName == nil) { + flutterAssetsName = @"Contents/Frameworks/App.framework/Resources/flutter_assets"; + } + return flutterAssetsName; +} + ++ (NSString*)lookupKeyForAsset:(NSString*)asset { + return [self lookupKeyForAsset:asset fromBundle:nil]; +} + ++ (NSString*)lookupKeyForAsset:(NSString*)asset fromBundle:(nullable NSBundle*)bundle { + NSString* flutterAssetsName = [FlutterDartProject flutterAssetsNameWithBundle:bundle]; + return [NSString stringWithFormat:@"%@/%@", flutterAssetsName, asset]; +} + ++ (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { + return [self lookupKeyForAsset:asset fromPackage:package fromBundle:nil]; +} + ++ (NSString*)lookupKeyForAsset:(NSString*)asset + fromPackage:(NSString*)package + fromBundle:(nullable NSBundle*)bundle { + return [self lookupKeyForAsset:[NSString stringWithFormat:@"packages/%@/%@", package, asset] + fromBundle:bundle]; +} + ++ (NSString*)defaultBundleIdentifier { + return kAppBundleIdentifier; +} + @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h index 214933669b039..0e0cad3757152 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h @@ -5,7 +5,8 @@ #ifndef SHELL_PLATFORM_DARWIN_MACOS_FRAMEWORK_SOURCE_FLUTTERDARTPROJECT_INTERNAL_H_ #define SHELL_PLATFORM_DARWIN_MACOS_FRAMEWORK_SOURCE_FLUTTERDARTPROJECT_INTERNAL_H_ -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterDartProject.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterDartProject.h" +#import "flutter/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h" #include #include diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 913b9a64f3ae5..3d3c60b69ff45 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -314,6 +314,14 @@ - (void)registerViewFactory:(nonnull NSObject*)facto [[_flutterEngine platformViewController] registerViewFactory:factory withId:factoryId]; } +- (NSString*)lookupKeyForAsset:(NSString*)asset { + return [FlutterDartProject lookupKeyForAsset:asset]; +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { + return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package]; +} + @end // Callbacks provided to the engine. See the called methods for documentation. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 48e725542c40d..4afb39c2f584b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -810,6 +810,14 @@ - (void)onKeyboardLayoutChanged { } } +- (NSString*)lookupKeyForAsset:(NSString*)asset { + return [FlutterDartProject lookupKeyForAsset:asset]; +} + +- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package { + return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package]; +} + #pragma mark - FlutterViewReshapeListener /** diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm index b48953923a38f..1e29259824147 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm @@ -66,6 +66,8 @@ - (bool)testMouseDownUpEventsSentToNextResponder; - (bool)testModifierKeysAreSynthesizedOnMouseMove; - (bool)testViewWillAppearCalledMultipleTimes; - (bool)testFlutterViewIsConfigured; +- (bool)testLookupKeyAssets; +- (bool)testLookupKeyAssetsWithPackage; + (void)respondFalseForSendEvent:(const FlutterKeyEvent&)event callback:(nullable FlutterKeyEventCallback)callback @@ -236,6 +238,14 @@ id MockGestureEvent(NSEventType type, NSEventPhase phase, double magnification, ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testFlutterViewIsConfigured]); } +TEST(FlutterViewControllerTest, testLookupKeyAssets) { + ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssets]); +} + +TEST(FlutterViewControllerTest, testLookupKeyAssetsWithPackage) { + ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssetsWithPackage]); +} + } // namespace flutter::testing #pragma mark - FlutterViewControllerTestObjC @@ -832,6 +842,24 @@ - (bool)testViewWillAppearCalledMultipleTimes { return true; } +- (bool)testLookupKeyAssets { + FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:nil]; + NSString* key = [viewController lookupKeyForAsset:@"test.png"]; + EXPECT_TRUE( + [key isEqualToString:@"Contents/Frameworks/App.framework/Resources/flutter_assets/test.png"]); + return true; +} + +- (bool)testLookupKeyAssetsWithPackage { + FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:nil]; + + NSString* packageKey = [viewController lookupKeyForAsset:@"test.png" fromPackage:@"test"]; + EXPECT_TRUE([packageKey + isEqualToString: + @"Contents/Frameworks/App.framework/Resources/flutter_assets/packages/test/test.png"]); + return true; +} + static void SwizzledNoop(id self, SEL _cmd) {} // Verify workaround an AppKit bug where mouseDown/mouseUp are not called on the view controller if @@ -874,6 +902,7 @@ - (bool)testMouseDownUpEventsSentToNextResponder { // Restore the original NSResponder mouseDown/mouseUp implementations. method_setImplementation(mouseDown, origMouseDown); method_setImplementation(mouseUp, origMouseUp); + return true; }