Merge pull request #11144 from dittos/mas-login-helper-again

Re-land MAS login helper (w/ regression fix)
This commit is contained in:
Cheng Zhao 2017-11-27 17:02:57 +09:00 коммит произвёл GitHub
Родитель 1c0ea0286e 71c16ad76f
Коммит c0e9dbcc00
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 152 добавлений и 27 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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>

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -6,6 +6,7 @@
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#import <ServiceManagement/ServiceManagement.h>
#include "base/callback.h"
#include "base/files/file_path.h"
@ -98,6 +99,10 @@ std::string OpenURL(NSURL* ns_url, bool activate) {
return "";
}
NSString* GetLoginHelperBundleIdentifier() {
return [[[NSBundle mainBundle] bundleIdentifier] stringByAppendingString:@".loginhelper"];
}
} // namespace
namespace platform_util {
@ -177,4 +182,26 @@ void Beep() {
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

Просмотреть файл

@ -893,30 +893,27 @@ need to pass the same arguments here for `openAtLogin` to be set correctly.
Returns `Object`:
* `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.
This setting is only supported on macOS.
* `wasOpenedAtLogin` Boolean - `true` if the app was opened at login
automatically. This setting is only supported on macOS.
* `wasOpenedAsHidden` Boolean - `true` if the app was opened as a hidden login
* `openAsHidden` Boolean _macOS_ - `true` if the app is set to open as hidden at login.
This setting is not available on [MAS builds][mas-builds].
* `wasOpenedAtLogin` Boolean _macOS_ - `true` if the app was opened at login
automatically. This setting is not available on [MAS builds][mas-builds].
* `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.
This setting is only supported on macOS.
* `restoreState` Boolean - `true` if the app was opened as a login item that
This setting is not available on [MAS builds][mas-builds].
* `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
app should restore the windows that were open the last time the app was
closed. This setting is only supported on macOS.
**Note:** This API has no effect on [MAS builds][mas-builds].
closed. This setting is not available on [MAS builds][mas-builds].
### `app.setLoginItemSettings(settings)` _macOS_ _Windows_
* `settings` Object
* `openAtLogin` Boolean (optional) - `true` to open the app at login, `false` to remove
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
`app.getLoginItemStatus().wasOpenedAsHidden` should be checked when the app
is opened to know the current value. This setting is only supported on
macOS.
is opened to know the current value. This setting is not available on [MAS builds][mas-builds].
* `path` String (optional) _Windows_ - The executable to launch at login.
Defaults to `process.execPath`.
* `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_
Returns `Boolean` - `true` if Chrome's accessibility support is enabled,

Просмотреть файл

@ -45,7 +45,7 @@ has your Team ID as value:
</plist>
```
Then, you need to prepare two entitlements files.
Then, you need to prepare three entitlements files.
`child.plist`:
@ -77,6 +77,19 @@ Then, you need to prepare two entitlements files.
</plist>
```
`loginhelper.plist`:
```xml
<?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/>
</dict>
</plist>
```
You have to replace `TEAM_ID` with your Team ID, and replace `your.bundle.id`
with the Bundle ID of your app.
@ -97,6 +110,7 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)"
# The path of your plist files.
CHILD_PLIST="/path/to/child.plist"
PARENT_PLIST="/path/to/parent.plist"
LOGINHELPER_PLIST="/path/to/loginhelper.plist"
FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
@ -110,6 +124,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 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 "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper"
codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_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 "$PARENT_PLIST" "$APP_PATH"
@ -162,8 +178,6 @@ and the following behaviors have been changed:
* Video capture may not work for some machines.
* Certain accessibility features may not work.
* 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
the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for

Просмотреть файл

@ -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=="win"', {
@ -577,6 +590,7 @@
'$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
'$(SDKROOT)/System/Library/Frameworks/ServiceManagement.framework',
],
},
'mac_bundle': 1,
@ -695,6 +709,32 @@
],
},
}, # 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"
],

Просмотреть файл

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

Просмотреть файл

@ -397,7 +397,7 @@ describe('app module', () => {
app.setLoginItemSettings({openAtLogin: false, path: updateExe, args: processStartArgs})
})
it('returns the login item status of the app', () => {
it('returns the login item status of the app', (done) => {
app.setLoginItemSettings({openAtLogin: true})
assert.deepEqual(app.getLoginItemSettings(), {
openAtLogin: true,
@ -410,20 +410,25 @@ describe('app module', () => {
app.setLoginItemSettings({openAtLogin: true, openAsHidden: true})
assert.deepEqual(app.getLoginItemSettings(), {
openAtLogin: true,
openAsHidden: process.platform === 'darwin', // Only available on macOS
openAsHidden: process.platform === 'darwin' && !process.mas, // Only available on macOS
wasOpenedAtLogin: false,
wasOpenedAsHidden: false,
restoreState: false
})
app.setLoginItemSettings({})
assert.deepEqual(app.getLoginItemSettings(), {
openAtLogin: false,
openAsHidden: false,
wasOpenedAtLogin: false,
wasOpenedAsHidden: false,
restoreState: false
})
// Wait because login item settings are not applied immediately in MAS build
const delay = process.mas ? 100 : 0
setTimeout(() => {
assert.deepEqual(app.getLoginItemSettings(), {
openAtLogin: false,
openAsHidden: false,
wasOpenedAtLogin: false,
wasOpenedAsHidden: false,
restoreState: false
})
done()
}, delay)
})
it('allows you to pass a custom executable and arguments', function () {