CEF Support sandbox on macOS now, what about Mac App Store?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby Czarek » Mon Sep 17, 2018 7:35 am

Maintainer of the CEF Python, PHP Desktop and CEF C API projects. Connect with me on LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1905
Joined: Sun Nov 06, 2011 2:12 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby hkurra » Thu Oct 11, 2018 1:24 am

Finally solved the problem as I mentioned in my last post :
Made changes in the chromium/base/mac/foundation_util.mm as follow
Return "XXXXXXXXXX.yyyy-group" from BaseBundleID() method, where XXXXXXXX is your Team ID, available under your apple developer portal and yyyy-group could be your app bundle Identifier
Build the CEF/Chromium code
Code Sign you Application with Following entitlements
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.apple.security.app-sandbox</key>
  <true/>
  <key>com.apple.security.application-groups</key>
  <string>TeamID.your.app.bundle.id</string>
</dict>
</plist>

Code sign your helper process Application with following entitlements:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.apple.security.app-sandbox</key>
  <true/>
  <key>com.apple.security.inherit</key>
  <true/>
</dict>
</plist>


Now the Question is can we have SetBaseBundleID() interface in CEF like it is there in Chromium(foundation_util.mm)? to avoid building CEF/chromium just for the sake of changing bundle identifier.
hkurra
Techie
 
Posts: 22
Joined: Wed Jun 21, 2017 8:13 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby Czarek » Thu Oct 11, 2018 1:36 am

Maintainer of the CEF Python, PHP Desktop and CEF C API projects. Connect with me on LinkedIn.
User avatar
Czarek
Virtuoso
 
Posts: 1905
Joined: Sun Nov 06, 2011 2:12 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby hkurra » Thu Oct 11, 2018 5:38 am

Thanks for your quick reply!
I am working on a branch 3497, these changes are not present on this branch.
Never mind, If I understood it correctly, through these changes we are setting the main application bundle ID, but for AppStore sandbox support we need to set TEAM-ID.bundleID, not only bundleID.
I know we can change our bundle ID to TEAM-ID.bundleID to make it run successfully, but we have already registered the Bundle ID of our Application, and I don't think we can change it after uploading the first build, even I believe it is not a right thing to add Team Id prefixed in your bundle ID(correct me if am wrong).
So my suggestion is to provide setting field through which we can override the bundle ID like we are doing it for the framework path.
hkurra
Techie
 
Posts: 22
Joined: Wed Jun 21, 2017 8:13 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby shannah » Fri Jan 22, 2021 2:28 pm

I know this is an old thread, but I'm hitting this issue now too.

In order for JCEF to work inside the Mac App Sandbox, I seem to need to add the `com.apple.security.application-groups` entitlement with a value of TEAMID.BUNDLEID

I also needed to set the CFBundleIdentifier of ALL Info.plist files to match this value. I.e. My CFBundleIdentifier must start with my TeamID. This seems wrong, and is problematic if I'm working with an app that already has a bundle ID.

Has anyone solved this issue in a way that doesn't require us to make the app's CFBundleIdentifier start with the team ID?
shannah
Techie
 
Posts: 30
Joined: Wed Jul 08, 2020 8:01 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby shannah » Fri Jan 22, 2021 2:42 pm

Actively researching this via trial and error.

It seems that using the app-groups entitlement may not be necessary after all. After changing the CFBundleId of *all* Info.plist files inside my main app bundle (including all helper apps and the Chromium Embedded Framework) to be the same as the root bundle ID, it seems to work inside the sandbox. Trying to upload to the appstore now to see if it fails any of the inspections.

For those who may be doing the same thing, I'm syncing the bundle IDs using the following command in my shell script that does the codesigning:

find "$APP_PATH" -name Info.plist -exec plutil -replace CFBundleIdentifier -string "$MY_BUNDLE_IDENTIFIER {} \;
shannah
Techie
 
Posts: 30
Joined: Wed Jul 08, 2020 8:01 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby shannah » Fri Jan 22, 2021 4:23 pm

Actually, I'm back to the same issue. turned out I was getting a bit of a "false positive" with my test of simply giving all bundles the same bundle ID. It seems that the Chromium Embedded Framework wasn't being signed because the structure is incorrect. After I fixed the structure, it signs properly, but it results in the app crashing:

FATAL:mach_port_rendezvous.cc(141) Check failed: kr == KERN_SUCCESS. bootstrap_check_in com.codename1.samples.BasicBrowserComponentSample.MachPortRendezvousServer.40578: Permission denied (1100)

This goes away if I set all bundle IDs to be include the TeamID as a prefix *and* add an entitlement for com.apple.security.application-groups with that same bundle ID (with the TeamID prefix).

The problem here is forcing the bundle ID to have the TeamID prefix is problematic. It may also be invalid. Not sure yet.

So original question? Has anybody got jcef working inside a Mac App Store app recently?
shannah
Techie
 
Posts: 30
Joined: Wed Jul 08, 2020 8:01 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby shannah » Mon Jan 25, 2021 4:35 pm

Posting this for the benefit of others who are trying to make java CEF work in Mac App sandbox, and Mac AppStore. There are some key elements to success:

1. The "Chromium Embedded Framework.framework" has a file structure that isn't "valid". It needs to be fixed. You can read about the structure at https://developer.apple.com/library/arc ... atomy.html. Here is a snippet from my codesigning script that shows how I transform the framework to a valid structure:
Code: Select all
CEF_FRAMEWORK="$APP_PATH/Frameworks/Chromium Embedded Framework.framework"
if [ -d "$CEF_FRAMEWORK" ] && [ ! -d "$CEF_FRAMEWORK/Versions" ]; then
    # The Chromium Embedded Framework comes malformed so Apple won't accept it. 
    # We need to fix it to be a valid format
    echo "Fixing structure of $CEF_FRAMEWORK so that Apple doesn't complain"
    mv "$CEF_FRAMEWORK" "${CEF_FRAMEWORK}-tmp"
    mkdir "$CEF_FRAMEWORK"
    mkdir "$CEF_FRAMEWORK/Versions"
    mv "${CEF_FRAMEWORK}-tmp" "$CEF_FRAMEWORK/Versions/A"
    CURR_DIRECTORY=`pwd`
    cd "$CEF_FRAMEWORK/Versions"
    ln -s A Current
    cd ..
    ln -s Versions/Current/Resources Resources
    ln -s Versions/Current/Libraries Libraries
    ln -s Versions/Current/"Chromium Embedded Framework" "Chromium Embedded Framework"
    cd "$CURR_DIRECTORY"
fi


TIP: It is important, when creating the symlinks in the above script that you DO NOT have a trailing slash in symlink paths. Otherwise codesigning will fail.

2. You MUST include the "com.apple.security.application-groups" entitlement. The name of this application group MUST start with your developer Team ID. Your team ID is easy to find in iTunes connect, or even just looking at your development certificate name. It is the code that is in the parenthesis at the end of your signing identity name. E.g. "Mac 3rd Party Developer XXXX (QYLULX7)". In this example it would be "QYLULX7".

3. You MUST change the CFBundleIdentifier of the "jcef Helper" applications so that they start with your the app group ID that you chose in step 2. This is because CEF uses mach ports to communicate and sets the service ID for these ports to a name that begins with the bundle ID. But the Mac app sandbox will only allow these apps to connect to these ports if their service name begins with a group name that is listed in the app-groups entitlement. Hence the bundle ID of the helper app needs to match the app group.

Here is a snippet from my codesigning script that handles the changing of these bundle IDs:

Code: Select all
if [ ! -z "$CN1_BUNDLE_IDENTIFIER" ]; then
    find "$APP_PATH"/Frameworks -name Info.plist -exec plutil -replace CFBundleIdentifier -string "$CN1_BUNDLE_IDENTIFIER" {} \;
fi


In the above example the $CN1_BUNDLE_IDENTIFIER is the bundle identifier I chose for the helper applications. This needs to start with the team ID and should match the app-group you've entered in your entitlements. The $APP_PATH is the path do your app bundle's Contents directory, and assumes that you have placed the helper apps (and the Chromium Embedded Framework.framework inside your MyApp.app/Contents/Frameworks directory.

4. In your java app, you must set the --framework-dir-path, --main-bundle-path, and --browser-subprocess-path arguments in the CefApp.startup(args) call. Here is a snippet from my java app as an example:

Code: Select all
private static String[] createArgs() {
        List<String> args = new ArrayList<String>();
        if (isMac) {
            if (!"true".equals(System.getProperty("cn1.cef.bundled"))) {
                // The cn1.cef.bundled flag is set in SEWrapper to indicate that CEF is bundled in the .app
                // Otherwise it needs to get CEF from the central location specified
                args.add(String.format("--framework-dir-path=%s/Chromium Embedded Framework.framework", getLibPath()));
                args.add(String.format("--main-bundle-path=%s/jcef Helper.app", getLibPath()));
                args.add(String.format("--browser-subprocess-path=%s/jcef Helper.app/Contents/MacOS/jcef Helper", getLibPath()));
            }
           
            args.add("--disable-gpu");
        } else if (isWindows) {
            // no extra stuff here
            //args.add(String.format("--browser-subprocess-path=%s\\jcef_helper.exer", getLibPath()));
           
            args.add("--disable-gpu");
            args.add("--disable-software-rasterizer");
            args.add("--disable-gpu-compositing");
        } else if (isUnix) {
            // no extra stuff here
            //args.add(String.format("--browser-subprocess-path=%s\\jcef_helper.exer", getLibPath()));
           
            args.add("--disable-gpu");
            args.add("--disable-software-rasterizer");
            args.add("--disable-gpu-compositing");
        } else {
            throw new UnsupportedOperationException("CEF Not implemented on this platform yet");
        }
        //args.add("--allow-file-access-from-files");
        args.add("--touch-events=enabled");
        args.add("--enable-media-stream");
        //args.add("--device-scale-factor=4");
        //args.add("--force-device-scale-factor=4");
        args.add("--autoplay-policy=no-user-gesture-required");
        args.add("--enable-usermedia-screen-capturing");
        //System.out.println("CEF Args: "+args);
        return args.toArray(new String[args.size()]);
    }
private static String getLibPath() {
        return System.getProperty("cef.libPath", null);
}


Notice that this relies on the "cef.libPath" system property to pass in the path to the Frameworks directory. I set this in the Info.plist file for my main app bundle. The following is the Info.plist file from sample app so you can see how that system property is set.

Code: Select all
<?xml version="1.0" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>BasicBrowserComponentSample</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
<key>CFBundleIdentifier</key>
<string>com.codename1.samples.BasicBrowserComponentSample</string>
<key>CFBundleDisplayName</key>
<string>BasicBrowserComponentSample</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>BasicBrowserComponentSample</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0.49</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2021 CodenameOne</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.business</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>JVMRuntime</key>
<string>jre</string>
<key>JVMMainClassName</key>
<string>com.codename1.samples.BasicBrowserComponentSampleStub</string>
<key>CFBundleDocumentTypes</key>
<array>
</array>
<key>LSArchitecturePriority</key>
<array>
<string>x86_64</string>
</array>
<key>LSEnvironment</key>
<dict>
<key>LC_CTYPE</key>
<string>UTF-8</string>
</dict>
<key>JVMOptions</key>
<array>
<string>-Xdock:name=BasicBrowserComponentSample</string>
<string>-Dapple.laf.useScreenMenuBar=true</string>
<string>-Dcom.apple.macos.use-file-dialog-packages=true</string>
<string>-Dcom.apple.macos.useScreenMenuBar=true</string>
<string>-Dcom.apple.mrj.application.apple.menu.about.name=BasicBrowserComponentSample</string>
<string>-Dcom.apple.smallTabs=true</string>
<string>-Dfile.encoding=UTF-8</string>
<string>-Djava.library.path=$APP_ROOT/Contents/Java/:$APP_ROOT/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries</string>
<string>-Dcef.libPath=$APP_ROOT/Contents/Frameworks</string>
<string>-Xmx1024M</string>
</array>
<key>JVMArguments</key>
<array>
</array>
</dict>
</plist>
shannah
Techie
 
Posts: 30
Joined: Wed Jul 08, 2020 8:01 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby shannah » Thu Jan 28, 2021 9:14 am

Update:

After jumping through all of these hoops, the Mac Appstore rejects apps using CEF anyways:

Guideline 2.5.1 - Performance

Your app links against the following non-public framework(s):

• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded Framework/CAContext
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/NSAccessibilityRemoteUIElement
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded Framework/NSNextStepFrame
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded Framework/NSThemeFrame
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded Framework/CALayerHost
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_dyld_dynamic_interpose
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSAppendToKillRing
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded Framework/_AudioDeviceDuck
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSDrawCarbonThemeBezel
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerGetBytePtr
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__kCFSystemVersionProductVersionExtraKey
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSYankFromKillRing
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSDrawCarbonThemeListBox
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSInitializeKillRing
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__CFCopySystemVersionDictionary
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerRangeCopyEndMarker
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerRangeCopyStartMarker
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__kCFSystemVersionProductNameKey
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSNewKillRingSequence
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_IOBluetoothPreferenceSetControllerPowerState
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__CFCopyServerVersionDictionary
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__LSSetApplicationLaunchServicesServerConnectionStatus
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__kCFSystemVersionProductVersionKey
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerCreate
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__kCFSystemVersionBuildVersionKey
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_xpc_mach_send_copy_right
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_NSTextInputReplacementRangeAttributeName
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerRangeGetTypeID
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_CFStringGetRangeOfCharacterClusterAtIndex
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerGetLength
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_xpc_mach_send_create
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerRangeCreate
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_SetApplicationIsDaemon
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__NSSetKillRingToYankedState
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_responsibility_spawnattrs_setdisclaim
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/__CFURLCreateFromPropertyListRepresentation
• Contents/Frameworks/Chromium Embedded
Framework.framework/Versions/A/Chromium Embedded
Framework/_AXTextMarkerGetTypeID


Seems like a long road ahead here.
shannah
Techie
 
Posts: 30
Joined: Wed Jul 08, 2020 8:01 am

Re: CEF Support sandbox on macOS now, what about Mac App Sto

Postby rado » Fri Feb 12, 2021 12:09 pm

I'm sorry I can't help you, I have only warning you should check all their terms. I've invested in iOS app which was rejected because although the iOS app was free, it was displaying data generated by paid windows application - which is not sold using apple's store. So when there is any money involved, they have to get their share or application is rejected.
rado
Expert
 
Posts: 109
Joined: Wed Oct 05, 2011 3:32 am

PreviousNext

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 14 guests