Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@cyanglaz
Copy link
Contributor

@cyanglaz cyanglaz commented Apr 6, 2023

original PR: #40332

  1. Add extension_safe flag to build the engine variant that is extension safe.
  2. Based on the above flag, compile out code that contains SharedApplication.

For testing, copy_and_verify_framework_module produces a warning message if the engine is not built with extension_safe when asked to. This warning message does not fail build on its own. A new CI step needs to be added to capture the warning message and fail.

fixes flutter/flutter#124286, flutter/flutter#124290, flutter/flutter#124289

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@cyanglaz cyanglaz requested a review from jmagman April 6, 2023 19:22
@cyanglaz cyanglaz requested a review from cbracken April 6, 2023 19:22
"-Werror=undeclared-selector",
]
if (extension_safe) {
flutter_cflags_objc += [ "-fapplication-extension" ]
Copy link
Contributor Author

@cyanglaz cyanglaz Apr 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macOS doesn't fail when building with this flag, but macOS does contain NSApplication code. I'm confused here.

@jmagman @cbracken

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get this working either, might take more investigation to see how what flags Xcode is passing through when it shows the warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the locally built mac engine.
Without with this flag, I got the warning when linking a share extension to the framework.
With this flag, there is no warning.
So it seemed like it is just working (which clearly is not since the mac os code does contain NSApplication.)

Will investigate more.
(I should have marked this PR as draft, it is not intended for reviewing yet before this macOS mystery is resolved)

Copy link
Contributor Author

@cyanglaz cyanglaz Apr 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into the headers, on iOS:

@property(class, nonatomic, readonly) UIApplication *sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
The shared application is marked as extension unavailable.

However, on macOS it is not.
@property (class, readonly, strong) __kindof NSApplication *sharedApplication;

In the document: https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW6 only linked to the UIApplication.sharedApplication, didn't mention NSApplication.

I create a sample mac framework having Require Only App-Extension-safe API turned on and having NSApplication.SharedApplication. It successfully compiled and a share extension can link to it without warning.

So I believe NSApplication.sharedApplication is compatible with extensions? So on mac, as long as the -fapplication-extension is in the build flags and there is no compile error, it will work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I believe NSApplication.sharedApplication is compatible with extensions? So on mac, as long as the -fapplication-extension is in the build flags and there is no compile error, it will work.

!!!
From my reading of the docs when they said sharedApplication without specifying an object I thought they meant either UIApplication or NSApplication.

Access a sharedApplication object, and so cannot use any of the methods on that object

If we don't need to do anything other than documentation for macOS that would be amazing!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also you could pull that very simple macOS flag-only work out of this so it would start working in the next stable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By "next stable" I just mean it can be available now-ish without needing to wait for all the iOS work to be correct.

@cyanglaz cyanglaz changed the title Build iOS Obj-C with -fapplication-extension flag Build iOS and macOS Obj-C with -fapplication-extension flag Apr 6, 2023
# Whether to build host-side development artifacts.
flutter_build_engine_artifacts = true

extension_safe = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe darwin_extension_safe and a comment? There are more "extension" concepts this could be confused with.


if (extension_safe) {
ldflags = [
"-F$framework_search_path",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprised this wasn't needed before... maybe copy_and_verify_framework_module isn't actually working (ignoring the extension stuff)?

#if !APPLICATION_EXTENSION_API_ONLY
// Checks if the top status bar should be visible. This platform ignores all
// other overlays

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do this in my prototype PR, but ideally we could get rid of as many sharedApplication usages as possible.
-[UIApplication statusBarHidden] is actually deprecated in iOS 13:

@property(readonly, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden API_UNAVAILABLE(tvos) API_DEPRECATED("Use the statusBarManager property of the window scene instead.", ios(2.0, 13.0));

Can you instead swap this to using the new API when 13 is @available, and fall back to sharedApplication statusBarHidden for older versions only? Probably best to do this in its own review though this can sit on in case it causes issues. I don't trust our testing coverage here.

From the [_engine.get() viewController] I think you could get .viewIfLoaded.window.windowScene?

I'm not sure if it's meaningful to have a status bar in an extension, though.

#if !APPLICATION_EXTENSION_API_ONLY
// Note: -[UIApplication setStatusBarStyle] is deprecated in iOS9
// in favor of delegating to the view controller
[[UIApplication sharedApplication] setStatusBarStyle:statusBarStyle];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setStatusBarStyle was deprecated in iOS 9 so we wouldn't even need a fallback or the macro (minimum is now iOS 11), if we can get a view controller here ([_engine.get() viewController]?)

- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated API_DEPRECATED("Use -[UIViewController preferredStatusBarStyle]", ios(2.0, 9.0)) API_UNAVAILABLE(tvos);

Though I don't really understand the delegateToViewController logic or why we wouldn't want to pass it along to the embedder... #2732

#if !APPLICATION_EXTENSION_API_ONLY
UIViewController* rootViewController =
[UIApplication sharedApplication].keyWindow.rootViewController;
if (engineViewController != rootViewController) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we still need to check something here in the share extension to avoid regressing #30939.

Comment on lines +1822 to +1823
UIWindowScene* windowScene = self.viewIfLoaded.window.windowScene;
[self performOrientationUpdateOnWindowScene:windowScene];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could just use this logic instead of anything in the #else, I didn't test it though so in my PR I only used it in the APPLICATION_EXTENSION_API_ONLY check.

} else {
#if !APPLICATION_EXTENSION_API_ONLY
UIInterfaceOrientationMask currentInterfaceOrientation =
1 << [[UIApplication sharedApplication] statusBarOrientation];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If available you could check the self.viewIfLoaded.window.windowScene.statusBarOrientation since this was deprecated in iOS 13.

@property(readonly, nonatomic) UIInterfaceOrientation statusBarOrientation API_UNAVAILABLE(tvos) API_DEPRECATED("Use the interfaceOrientation property of the window scene instead.", ios(2.0, 13.0));

Comment on lines +1978 to +1990
UIContentSizeCategory category =
self.mainScreenIfViewLoaded.traitCollection.preferredContentSizeCategory;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just use this in all cases since this is all available on iOS 10+, but I didn't test it so I put it in the macro for safety in my PR.

"-Werror=undeclared-selector",
]
if (extension_safe) {
flutter_cflags_objc += [ "-fapplication-extension" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get this working either, might take more investigation to see how what flags Xcode is passing through when it shows the warning.

@cyanglaz cyanglaz marked this pull request as draft April 7, 2023 17:10
@flutter-dashboard
Copy link

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

output_name = "Flutter"

ldflags = [ "-Wl,-install_name,@rpath/Flutter.framework/Flutter" ]
ldflags = [ "-Wl,-install_name,&_flutter_framework_dir/Flutter" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ldflags = [ "-Wl,-install_name,&_flutter_framework_dir/Flutter" ]
ldflags = [ "-Wl,-install_name,$_flutter_framework_dir/Flutter" ]

@cyanglaz cyanglaz force-pushed the app_extension branch 2 times, most recently from f1154c2 to 5761631 Compare April 17, 2023 20:25
@cyanglaz cyanglaz changed the title Build iOS and macOS Obj-C with -fapplication-extension flag Build iOS with -fapplication-extension flag Apr 17, 2023
Build iOS and macOS Obj-C with -fapplication-extension flag

Linker flag

Find the App.framework asset URL from the app extension

Remove load

draft

extension safe built flag

format gn

format

macos test

fix clang tidy

rename flag

add linker flag

format

draft

format:

add LINE EOF

fix typo

format

fix run search path

fix copying

fix build.gn

format

format
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[app_extension_safe] engine build flag to expose an extension safe Flutter.framework/FlutterMacOS.framework

2 participants