Implement login helper to manage login item in Mac App Store build

This commit is contained in:
Ted Kim 2017-10-17 16:28:29 +09:00
parent 306b627090
commit 4119da607f
9 changed files with 123 additions and 17 deletions

View file

@ -0,0 +1,11 @@
#import <Cocoa/Cocoa.h>
int main(int argc, char* argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
NSString* path = [NSString pathWithComponents:pathComponents];
[[NSWorkspace sharedWorkspace] launchApplication:path];
[pool drain];
return 0;
}

View file

@ -0,0 +1,16 @@
<?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>CFBundleIdentifier</key>
<string>${ATOM_BUNDLE_ID}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>LSBackgroundOnly</key>
<true/>
</dict>
</plist>

View file

@ -4,6 +4,7 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/common/platform_util.h"
#include "atom/browser/mac/atom_application.h" #include "atom/browser/mac/atom_application.h"
#include "atom/browser/mac/atom_application_delegate.h" #include "atom/browser/mac/atom_application_delegate.h"
#include "atom/browser/mac/dict_util.h" #include "atom/browser/mac/dict_util.h"
@ -193,19 +194,27 @@ bool Browser::UpdateUserActivityState(const std::string& type,
Browser::LoginItemSettings Browser::GetLoginItemSettings( Browser::LoginItemSettings Browser::GetLoginItemSettings(
const LoginItemSettings& options) { const LoginItemSettings& options) {
LoginItemSettings settings; LoginItemSettings settings;
#if defined(MAS_BUILD)
settings.open_at_login = platform_util::GetLoginItemEnabled();
#else
settings.open_at_login = base::mac::CheckLoginItemStatus( settings.open_at_login = base::mac::CheckLoginItemStatus(
&settings.open_as_hidden); &settings.open_as_hidden);
settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState(); settings.restore_state = base::mac::WasLaunchedAsLoginItemRestoreState();
settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem(); settings.opened_at_login = base::mac::WasLaunchedAsLoginOrResumeItem();
settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem(); settings.opened_as_hidden = base::mac::WasLaunchedAsHiddenLoginItem();
#endif
return settings; return settings;
} }
void Browser::SetLoginItemSettings(LoginItemSettings settings) { void Browser::SetLoginItemSettings(LoginItemSettings settings) {
#if defined(MAS_BUILD)
platform_util::SetLoginItemEnabled(settings.open_at_login);
#else
if (settings.open_at_login) if (settings.open_at_login)
base::mac::AddToLoginItems(settings.open_as_hidden); base::mac::AddToLoginItems(settings.open_as_hidden);
else else
base::mac::RemoveFromLoginItems(); base::mac::RemoveFromLoginItems();
#endif
} }
std::string Browser::GetExecutableFileVersion() const { std::string Browser::GetExecutableFileVersion() const {

View file

@ -57,6 +57,11 @@ bool MoveItemToTrash(const base::FilePath& full_path);
void Beep(); void Beep();
#if defined(OS_MACOSX)
bool GetLoginItemEnabled();
void SetLoginItemEnabled(bool enabled);
#endif
} // namespace platform_util } // namespace platform_util
#endif // ATOM_COMMON_PLATFORM_UTIL_H_ #endif // ATOM_COMMON_PLATFORM_UTIL_H_

View file

@ -6,6 +6,7 @@
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <ServiceManagement/ServiceManagement.h>
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
@ -98,6 +99,10 @@ std::string OpenURL(NSURL* ns_url, bool activate) {
return ""; return "";
} }
NSString* GetLoginHelperBundleIdentifier() {
return [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".loginhelper"];
}
} // namespace } // namespace
namespace platform_util { namespace platform_util {
@ -177,4 +182,26 @@ void Beep() {
NSBeep(); NSBeep();
} }
bool GetLoginItemEnabled() {
BOOL enabled = NO;
// SMJobCopyDictionary does not work in sandbox (see rdar://13626319)
CFArrayRef jobs = SMCopyAllJobDictionaries(kSMDomainUserLaunchd);
NSArray* jobs_ = CFBridgingRelease(jobs);
NSString* identifier = GetLoginHelperBundleIdentifier();
if (jobs_ && [jobs_ count] > 0) {
for (NSDictionary* job in jobs_) {
if ([identifier isEqualToString:[job objectForKey:@"Label"]]) {
enabled = [[job objectForKey:@"OnDemand"] boolValue];
break;
}
}
}
return enabled;
}
void SetLoginItemEnabled(bool enabled) {
NSString* identifier = GetLoginHelperBundleIdentifier();
SMLoginItemSetEnabled((__bridge CFStringRef) identifier, enabled);
}
} // namespace platform_util } // namespace platform_util

View file

@ -893,30 +893,27 @@ need to pass the same arguments here for `openAtLogin` to be set correctly.
Returns `Object`: Returns `Object`:
* `openAtLogin` Boolean - `true` if the app is set to open at login. * `openAtLogin` Boolean - `true` if the app is set to open at login.
* `openAsHidden` Boolean - `true` if the app is set to open as hidden at login. * `openAsHidden` Boolean _macOS_ - `true` if the app is set to open as hidden at login.
This setting is only supported on macOS. This setting is not available on [MAS builds][mas-builds].
* `wasOpenedAtLogin` Boolean - `true` if the app was opened at login * `wasOpenedAtLogin` Boolean _macOS_ - `true` if the app was opened at login
automatically. This setting is only supported on macOS. automatically. This setting is not available on [MAS builds][mas-builds].
* `wasOpenedAsHidden` Boolean - `true` if the app was opened as a hidden login * `wasOpenedAsHidden` Boolean _macOS_ - `true` if the app was opened as a hidden login
item. This indicates that the app should not open any windows at startup. item. This indicates that the app should not open any windows at startup.
This setting is only supported on macOS. This setting is not available on [MAS builds][mas-builds].
* `restoreState` Boolean - `true` if the app was opened as a login item that * `restoreState` Boolean _macOS_ - `true` if the app was opened as a login item that
should restore the state from the previous session. This indicates that the should restore the state from the previous session. This indicates that the
app should restore the windows that were open the last time the app was app should restore the windows that were open the last time the app was
closed. This setting is only supported on macOS. closed. This setting is not available on [MAS builds][mas-builds].
**Note:** This API has no effect on [MAS builds][mas-builds].
### `app.setLoginItemSettings(settings)` _macOS_ _Windows_ ### `app.setLoginItemSettings(settings)` _macOS_ _Windows_
* `settings` Object * `settings` Object
* `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove * `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove
the app as a login item. Defaults to `false`. the app as a login item. Defaults to `false`.
* `openAsHidden` Boolean (optional) - `true` to open the app as hidden. Defaults to * `openAsHidden` Boolean (optional) _macOS_ - `true` to open the app as hidden. Defaults to
`false`. The user can edit this setting from the System Preferences so `false`. The user can edit this setting from the System Preferences so
`app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app `app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app
is opened to know the current value. This setting is only supported on is opened to know the current value. This setting is not available on [MAS builds][mas-builds].
macOS.
* `path` String (optional) _Windows_ - The executable to launch at login. * `path` String (optional) _Windows_ - The executable to launch at login.
Defaults to `process.execPath`. Defaults to `process.execPath`.
* `args` String[] (optional) _Windows_ - The command-line arguments to pass to * `args` String[] (optional) _Windows_ - The command-line arguments to pass to
@ -944,8 +941,6 @@ app.setLoginItemSettings({
}) })
``` ```
**Note:** This API has no effect on [MAS builds][mas-builds].
### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_ ### `app.isAccessibilitySupportEnabled()` _macOS_ _Windows_
Returns `Boolean` - `true` if Chrome's accessibility support is enabled, Returns `Boolean` - `true` if Chrome's accessibility support is enabled,

View file

@ -110,6 +110,8 @@ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP H
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"
@ -162,8 +164,6 @@ and the following behaviors have been changed:
* Video capture may not work for some machines. * Video capture may not work for some machines.
* Certain accessibility features may not work. * Certain accessibility features may not work.
* Apps will not be aware of DNS changes. * Apps will not be aware of DNS changes.
* APIs for launching apps at login are disabled. See
https://github.com/electron/electron/issues/7312#issuecomment-249479237
Also, due to the usage of app sandboxing, the resources which can be accessed by Also, due to the usage of app sandboxing, the resources which can be accessed by
the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for

View file

@ -122,6 +122,19 @@
}, },
], ],
}], }],
['mas_build==1', {
'dependencies': [
'<(project_name)_login_helper',
],
'copies': [
{
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Library/LoginItems',
'files': [
'<(PRODUCT_DIR)/<(product_name) Login Helper.app',
],
},
],
}],
], ],
}], # OS!="mac" }], # OS!="mac"
['OS=="win"', { ['OS=="win"', {
@ -566,6 +579,7 @@
'$(SDKROOT)/System/Library/Frameworks/Quartz.framework', '$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
'$(SDKROOT)/System/Library/Frameworks/Security.framework', '$(SDKROOT)/System/Library/Frameworks/Security.framework',
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework', '$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
'$(SDKROOT)/System/Library/Frameworks/ServiceManagement.framework',
], ],
}, },
'mac_bundle': 1, 'mac_bundle': 1,
@ -684,6 +698,32 @@
], ],
}, },
}, # target helper }, # target helper
{
'target_name': '<(project_name)_login_helper',
'product_name': '<(product_name) Login Helper',
'type': 'executable',
'sources': [
'<@(login_helper_sources)',
],
'include_dirs': [
'.',
'vendor',
'<(libchromiumcontent_src_dir)',
],
'link_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/AppKit.framework',
],
},
'mac_bundle': 1,
'xcode_settings': {
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).loginhelper',
'INFOPLIST_FILE': 'atom/app/resources/mac/loginhelper-Info.plist',
'OTHER_LDFLAGS': [
'-ObjC',
],
},
}, # target login_helper
], ],
}], # OS!="mac" }], # OS!="mac"
], ],

View file

@ -661,6 +661,9 @@
'atom/app/atom_library_main.h', 'atom/app/atom_library_main.h',
'atom/app/atom_library_main.mm', 'atom/app/atom_library_main.mm',
], ],
'login_helper_sources': [
'atom/app/atom_login_helper.mm',
],
'locales': [ 'locales': [
'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB', 'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB',
'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he', 'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he',