ELECTRON-635 (Custom auto launch implementation)[Windows] (#484)

* ELECTRON-635: add support for auto launch custom path

* ELECTRON-635 - autolaunch aip testing

* ELECTRON-635 - Add quot

* ELECTRON-635 - Escape quot

* ELECTRON-635 - Escape quot

* ELECTRON-635 - Fix escape auto launch path

* ELECTRON-635 - Fix escape auto launch path

* ELECTRON-635 - Fix escape auto launch path

* ELECTRON-635 - add empty property to the AUTO_LAUNCH_PATH property

* ELECTRON-635 - final fix for auto launch

* ELECTRON-635 - Fix auto launch issue

* ELECTRON-635 - Fix path escape

* ELECTRON-635 - Fix first time launch

* ELECTRON-635 - Mock app.getVersion

* ELECTRON-635 - Fix per user app path
This commit is contained in:
Kiran Niranjan
2018-08-30 22:58:07 +05:30
committed by Vishwas Shashidhar
parent 0d04ac03e2
commit 274f4811f0
9 changed files with 132 additions and 117 deletions

View File

@@ -31,5 +31,6 @@
"pointerLock": true,
"fullscreen": true,
"openExternal": true
}
},
"autoLaunchPath": ""
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

60
js/autoLaunch/index.js Normal file
View File

@@ -0,0 +1,60 @@
const AutoLaunch = require('auto-launch');
// Local Dependencies
const log = require('../log.js');
const logLevels = require('../enums/logLevels.js');
const { readConfigFileSync } = require('../config.js');
const { isMac } = require('../utils/misc.js');
const globalConfigData = readConfigFileSync();
const props = isMac ? {
name: 'Symphony',
mac: {
useLaunchAgent: true,
},
path: process.execPath,
} : {
name: 'Symphony',
path: getAutoLaunchPath() || process.execPath,
};
class AutoLaunchController extends AutoLaunch {
constructor(opts) {
super(opts);
}
/**
* Enable auto launch
* @return {Promise<void>}
*/
enableAutoLaunch() {
log.send(logLevels.INFO, `Enabling auto launch!`);
return this.enable();
}
/**
* Disable auto launch
* @return {Promise<void>}
*/
disableAutoLaunch() {
log.send(logLevels.INFO, `Disabling auto launch!`);
return this.disable();
}
}
/**
* Replace forward slash in the path to backward slash
* @return {any}
*/
function getAutoLaunchPath() {
const autoLaunchPath = globalConfigData && globalConfigData.autoLaunchPath || null;
return autoLaunchPath ? autoLaunchPath.replace(/\//g, '\\') : null;
}
const autoLaunchInstance = new AutoLaunchController(props);
module.exports = {
enable: autoLaunchInstance.enableAutoLaunch.bind(autoLaunchInstance),
disable: autoLaunchInstance.disableAutoLaunch.bind(autoLaunchInstance)
};

View File

@@ -77,8 +77,6 @@ function getUserConfigField(fieldName) {
*/
function readUserConfig(customConfigPath) {
log.send(logLevels.INFO, `custom config path ${customConfigPath}`);
return new Promise((resolve, reject) => {
if (userConfig) {
@@ -197,7 +195,7 @@ function updateConfigField(fieldName, newValue) {
// add configVersion - just in case in future we need to provide
// upgrade capabilities.
return saveUserConfig(fieldName, newValue, {
configVersion: '1.0.0'
configVersion: app.getVersion().toString(),
});
});
}
@@ -258,14 +256,18 @@ function updateUserConfig(oldUserConfig) {
userConfigFile = path.join(app.getPath('userData'), configFileName);
if (!userConfigFile) {
return reject(`user config file doesn't exist`);
reject(`user config file doesn't exist`);
return;
}
// write the new user config changes to the user config file
fs.writeFileSync(userConfigFile, newUserConfigString, 'utf-8');
return resolve();
fs.writeFile(userConfigFile, newUserConfigString, 'utf-8', (err) => {
if (err) {
reject(`Failed to update user config error: ${err}`);
return;
}
resolve();
});
});
}
@@ -275,9 +277,6 @@ function updateUserConfig(oldUserConfig) {
* @returns {Promise}
*/
function updateUserConfigOnLaunch() {
return new Promise((resolve, reject) => {
// we get the user config path using electron
const userConfigFile = path.join(app.getPath('userData'), configFileName);
@@ -285,23 +284,20 @@ function updateUserConfigOnLaunch() {
// user config file doesn't exist, we simple move on
if (!fs.existsSync(userConfigFile)) {
log.send(logLevels.WARN, 'config: Could not find the user config file!');
reject();
return;
return Promise.reject('config: Could not find the user config file!');
}
// In case the file exists, we remove it so that all the
// values are fetched from the global config
// https://perzoinc.atlassian.net/browse/ELECTRON-126
readUserConfig(userConfigFile).then((data) => {
return readUserConfig(userConfigFile).then((data) => {
// Add version info to the user config data
const version = app.getVersion().toString();
const updatedData = Object.assign(data, { version });
const version = app.getVersion().toString() || '1.0.0';
const updatedData = Object.assign(data || {}, { configVersion: version });
resolve(updateUserConfig(updatedData));
return updateUserConfig(updatedData);
}).catch((err) => {
reject(err);
});
return Promise.reject(err);
});
}

View File

@@ -7,7 +7,6 @@ const crashReporter = electron.crashReporter;
const nodeURL = require('url');
const shellPath = require('shell-path');
const squirrelStartup = require('electron-squirrel-startup');
const AutoLaunch = require('auto-launch');
const urlParser = require('url');
const nodePath = require('path');
const compareSemVersions = require('./utils/compareSemVersions.js');
@@ -15,7 +14,6 @@ const compareSemVersions = require('./utils/compareSemVersions.js');
// Local Dependencies
const {
getConfigField,
getGlobalConfigField,
readConfigFileSync,
updateUserConfigOnLaunch,
getUserConfigField
@@ -26,6 +24,7 @@ const protocolHandler = require('./protocolHandler');
const getCmdLineArg = require('./utils/getCmdLineArg.js');
const log = require('./log.js');
const logLevels = require('./enums/logLevels.js');
const autoLaunch = require('./autoLaunch');
require('electron-dl')();
@@ -95,23 +94,6 @@ if (!allowMultiInstance && shouldQuit) {
app.quit();
}
let symphonyAutoLauncher;
if (isMac) {
symphonyAutoLauncher = new AutoLaunch({
name: 'Symphony',
mac: {
useLaunchAgent: true,
},
path: process.execPath,
});
} else {
symphonyAutoLauncher = new AutoLaunch({
name: 'Symphony',
path: process.execPath,
});
}
/**
* Sets chrome authentication flags in electron
*/
@@ -204,7 +186,8 @@ setChromeFlags();
*/
app.on('ready', () => {
checkFirstTimeLaunch()
.then(readConfigThenOpenMainWindow);
.then(readConfigThenOpenMainWindow)
.catch(readConfigThenOpenMainWindow);
});
/**
@@ -282,31 +265,24 @@ function setupThenOpenMainWindow() {
}
function checkFirstTimeLaunch() {
return new Promise((resolve) => {
getUserConfigField('version')
return getUserConfigField('configVersion')
.then((configVersion) => {
const appVersionString = app.getVersion().toString();
const execPath = nodePath.dirname(app.getPath('exe'));
const shouldUpdateUserConfig = execPath.indexOf('AppData/Local/Programs') !== -1 || isMac;
const shouldUpdateUserConfig = execPath.indexOf('AppData\\Local\\Programs') !== -1 || isMac;
if (!(configVersion
&& typeof configVersion === 'string'
&& (compareSemVersions.check(appVersionString, configVersion) !== 1)) && shouldUpdateUserConfig) {
return setupFirstTimeLaunch();
}
return resolve();
log.send(logLevels.INFO, `not a first-time launch as
configVersion: ${configVersion} appVersion: ${appVersionString} shouldUpdateUserConfig: ${shouldUpdateUserConfig}`);
return Promise.resolve();
})
.catch(() => {
return setupFirstTimeLaunch();
});
return resolve();
});
}
/**
@@ -316,20 +292,10 @@ function checkFirstTimeLaunch() {
* @return {Promise<any>}
*/
function setupFirstTimeLaunch() {
return new Promise(resolve => {
log.send(logLevels.INFO, 'setting first time launch config');
getGlobalConfigField('launchOnStartup')
return getConfigField('launchOnStartup')
.then(setStartup)
.then(updateUserConfigOnLaunch)
.then(() => {
log.send(logLevels.INFO, 'first time launch config changes succeeded -> ');
return resolve();
})
.catch((err) => {
log.send(logLevels.ERROR, 'first time launch config changes failed -> ' + err);
return resolve();
});
});
.then(updateUserConfigOnLaunch);
}
/**
@@ -344,10 +310,10 @@ function setStartup(lStartup) {
log.send(logLevels.INFO, `launchOnStartup value is ${launchOnStartup}`);
if (launchOnStartup) {
log.send(logLevels.INFO, `enabling launch on startup`);
symphonyAutoLauncher.enable();
autoLaunch.enable();
return resolve();
}
symphonyAutoLauncher.disable();
autoLaunch.disable();
return resolve();
});
}

View File

@@ -1,7 +1,6 @@
'use strict';
const fs = require('fs');
const AutoLaunch = require('auto-launch');
const electron = require('electron');
const { updateConfigField, getMultipleConfigField } = require('../config.js');
@@ -13,6 +12,7 @@ const eventEmitter = require('../eventEmitter');
const aboutApp = require('../aboutApp');
const titleBarStyles = require('../enums/titleBarStyles');
const i18n = require('../translation/i18n');
const autoLaunch = require('../autoLaunch');
const configFields = [
'minimizeOnClose',
@@ -31,8 +31,6 @@ let bringToFront = false;
let memoryRefresh = false;
let titleBarStyle = titleBarStyles.CUSTOM;
let symphonyAutoLauncher;
const windowsAccelerator = Object.assign({
undo: 'Ctrl+Z',
redo: 'Ctrl+Y',
@@ -49,21 +47,6 @@ const windowsAccelerator = Object.assign({
close: 'Ctrl+W',
});
if (isMac) {
symphonyAutoLauncher = new AutoLaunch({
name: 'Symphony',
mac: {
useLaunchAgent: true,
},
path: process.execPath,
});
} else {
symphonyAutoLauncher = new AutoLaunch({
name: 'Symphony',
path: process.execPath,
});
}
function getTemplate(app) {
const template = [{
@@ -306,7 +289,7 @@ function getTemplate(app) {
checked: launchOnStartup,
click: function (item, focusedWindow) {
if (item.checked) {
symphonyAutoLauncher.enable()
autoLaunch.enable()
.catch(function (err) {
let title = 'Error setting AutoLaunch configuration';
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
@@ -319,7 +302,7 @@ function getTemplate(app) {
}
});
} else {
symphonyAutoLauncher.disable()
autoLaunch.disable()
.catch(function (err) {
let title = 'Error setting AutoLaunch configuration';
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);

View File

@@ -17,11 +17,16 @@ let userConfigDir;
jest.mock('electron', function() {
return {
app: {
getPath: mockedGetPath
getPath: mockedGetPath,
getVersion: mockedGetVersion
}
}
});
function mockedGetVersion() {
return '3.1.0';
}
function mockedGetPath(type) {
if (type === 'exe') {
return globalConfigDir;