diff --git a/src/browser/api/system.js b/src/browser/api/system.js index 8db00e5dd..caa488e05 100644 --- a/src/browser/api/system.js +++ b/src/browser/api/system.js @@ -14,10 +14,10 @@ const crypto = require('crypto'); const _ = require('underscore'); // local modules -import convertOptions from '../convert_options.js'; +import optionsConverter from '../convert_options.js'; import * as coreState from '../core_state.js'; import { ExternalApplication } from './external_application'; -import * as log from '../log'; +import * as logger from '../log'; import ofEvents from '../of_events'; import ProcessTracker from '../process_tracker.js'; import socketServer from '../transports/socket_server'; @@ -106,660 +106,723 @@ eventPropagationMap.forEach((systemEvent, eventString) => { }); }); -export const System = { - addEventListener: function(type, listener) { - ofEvents.on(route.system(type), listener); +export function addEventListener(type, listener) { + ofEvents.on(route.system(type), listener); - var unsubscribe = () => { - ofEvents.removeListener(route.system(type), listener); - }; + var unsubscribe = () => { + ofEvents.removeListener(route.system(type), listener); + }; + + return unsubscribe; +} +export function authenticateResourceFetch(identity, options) { + authenticateFetch(options.uuid, options.username, options.password); +} +export function clearCache(identity, options, resolve) { + /* + fin.desktop.System.clearCache({ + cache: true, + cookies: true, + localStorage: true, + appcache: true, + userData: true // TODO: userData is the window bounds cache + }); + */ + var settings = options || {}; - return unsubscribe; - }, - authenticateResourceFetch: function(identity, options) { - authenticateFetch(options.uuid, options.username, options.password); - }, - clearCache: function(identity, options, resolve) { - /* - fin.desktop.System.clearCache({ - cache: true, - cookies: true, - localStorage: true, - appcache: true, - userData: true // TODO: userData is the window bounds cache - }); - */ - var settings = options || {}; + const availableStorages = ['appcache', 'cookies', 'filesystem', 'indexdb', 'localstorage', 'shadercache', 'websql', 'serviceworkers']; + const storages = []; - const availableStorages = ['appcache', 'cookies', 'filesystem', 'indexdb', 'localstorage', 'shadercache', 'websql', 'serviceworkers']; - const storages = []; + if (typeof settings.localStorage === 'boolean') { + settings.localstorage = settings.localStorage; + } - if (typeof settings.localStorage === 'boolean') { - settings.localstorage = settings.localStorage; - } + // 5.0 defaults cache true if not specified + if (Object.keys(settings).length === 0) { + settings.cache = true; + } + if (typeof settings.cache === 'boolean') { + settings.filesystem = settings.filesystem || settings.cache; + settings.indexdb = settings.indexdb || settings.cache; + settings.shadercache = settings.shadercache || settings.cache; + settings.websql = settings.websql || settings.cache; + settings.serviceworkers = settings.serviceworkers || settings.cache; + } - // 5.0 defaults cache true if not specified - if (Object.keys(settings).length === 0) { - settings.cache = true; - } - if (typeof settings.cache === 'boolean') { - settings.filesystem = settings.filesystem || settings.cache; - settings.indexdb = settings.indexdb || settings.cache; - settings.shadercache = settings.shadercache || settings.cache; - settings.websql = settings.websql || settings.cache; - settings.serviceworkers = settings.serviceworkers || settings.cache; + availableStorages.forEach(function(key) { + if (settings[key]) { + storages.push(key); } + }); - availableStorages.forEach(function(key) { - if (settings[key]) { - storages.push(key); - } - }); - - const cacheOptions = { - /* origin? */ - storages: storages, - quotas: ['temporary', 'persistent', 'syncable'] - }; + const cacheOptions = { + /* origin? */ + storages: storages, + quotas: ['temporary', 'persistent', 'syncable'] + }; - electronApp.vlog(1, `clearCache ${JSON.stringify(storages)}`); + electronApp.vlog(1, `clearCache ${JSON.stringify(storages)}`); - grantAccess(async () => { - try { - await defaultSession.clearCache().then(() => { - defaultSession.clearStorageData(cacheOptions, () => { - resolve(); - }); + grantAccess(async () => { + try { + await defaultSession.clearCache().then(() => { + defaultSession.clearStorageData(cacheOptions, () => { + resolve(); }); - } catch (e) { - resolve(e); - } - }); - }, - createProxySocket: function(options, callback, errorCallback) { - createChromiumSocket(Object.assign({}, options, { callback, errorCallback })); - }, - authenticateProxySocket: function(options) { - const url = options && options.url; - electronApp.vlog(1, `authenticateProxySocket ${url}`); - authenticateChromiumSocket(options); - }, - deleteCacheOnExit: function(callback, errorCallback) { - const folders = [{ - name: electronApp.getPath('userData') // deleteIfEmpty defaults to false on RVM side - }, { - name: electronApp.getPath('userDataRoot'), - deleteIfEmpty: true - }]; - - const publishSuccess = rvmBus.publish({ - topic: 'cleanup', - folders - }); - - if (publishSuccess) { - callback(); - } else { - errorCallback('Failed to send a message to the RVM.'); + }); + } catch (e) { + resolve(e); } - }, - exit: function() { - electronApp.quit(); - }, - getAllWindows: function() { - return coreState.getAllWindows(); - }, - getAllApplications: function() { - return coreState.getAllApplications(); - }, - getAppAssetInfo: function(identity, options, callback, errorCallback) { - options.srcUrl = coreState.getConfigUrlByUuid(identity.uuid); - // TODO: Move this require to the top of file during future 'dependency injection refactor' - // Must require here otherwise runtime error Cannot create browser window before app is ready - var appAssetsFetcher = require('../rvm/runtime_initiated_topics/app_assets').appAssetsFetcher; - appAssetsFetcher.fetchAppAsset(options.srcUrl, options.alias, callback, errorCallback); - }, - getCommandLineArguments: function() { - return electronApp.getCommandLineArguments(); - }, - getConfig: function() { - return coreState.getStartManifest(); - }, - getCrashReporterState: function() { - return crashReporter.crashReporterState(); - }, - getDeviceUserId: function() { - const hash = crypto.createHash('sha256'); + }); +} +export function createProxySocket(options, callback, errorCallback) { + createChromiumSocket(Object.assign({}, options, { callback, errorCallback })); +} +export function authenticateProxySocket(options) { + const url = options && options.url; + electronApp.vlog(1, `authenticateProxySocket ${url}`); + authenticateChromiumSocket(options); +} +export function deleteCacheOnExit(callback, errorCallback) { + const folders = [{ + name: electronApp.getPath('userData') // deleteIfEmpty defaults to false on RVM side + }, { + name: electronApp.getPath('userDataRoot'), + deleteIfEmpty: true + }]; + + const publishSuccess = rvmBus.publish({ + topic: 'cleanup', + folders + }); - let hostToken; - let username; + if (publishSuccess) { + callback(); + } else { + errorCallback('Failed to send a message to the RVM.'); + } +} +export function exit() { + electronApp.quit(); +} +export function getAllWindows() { + return coreState.getAllWindows(); +} +export function getAllApplications() { + return coreState.getAllApplications(); +} +export function getAppAssetInfo(identity, options, callback, errorCallback) { + options.srcUrl = coreState.getConfigUrlByUuid(identity.uuid); + // TODO: Move this require to the top of file during future 'dependency injection refactor' + // Must require here otherwise runtime error Cannot create browser window before app is ready + var appAssetsFetcher = require('../rvm/runtime_initiated_topics/app_assets').appAssetsFetcher; + appAssetsFetcher.fetchAppAsset(options.srcUrl, options.alias, callback, errorCallback); +} +export function getCommandLineArguments() { + return electronApp.getCommandLineArguments(); +} +export function getConfig() { + return coreState.getStartManifest(); +} +export function getCrashReporterState() { + return crashReporter.crashReporterState(); +} +export function getDeviceUserId() { + const hash = crypto.createHash('sha256'); + + let hostToken; + let username; + + if (process.platform === 'darwin') { + hostToken = os.networkInterfaces().en0[0].mac; + username = process.env.USER; + } else { + + // assume windows + hostToken = electronApp.getHostToken(); + username = process.env.USERNAME; + } - if (process.platform === 'darwin') { - hostToken = os.networkInterfaces().en0[0].mac; - username = process.env.USER; - } else { + if (!username || !hostToken) { + throw new Error(`One of username (${username}) or host token (${hostToken}) not defined`); + } - // assume windows - hostToken = electronApp.getHostToken(); - username = process.env.USERNAME; - } + hash.update(hostToken); + hash.update(username); - if (!username || !hostToken) { - throw new Error(`One of username (${username}) or host token (${hostToken}) not defined`); - } + return hash.digest('hex'); +} +export function getDeviceId() { + if (process.platform === 'win32') { + return electronApp.getHostToken(); + } else { + const hash = crypto.createHash('sha256'); - hash.update(hostToken); - hash.update(username); + const macAddress = os.networkInterfaces().en0[0].mac; + if (!macAddress) { + throw new Error(`MAC address (${macAddress}) not defined`); + } + hash.update(macAddress); return hash.digest('hex'); - }, - getDeviceId: function() { - if (process.platform === 'win32') { - return electronApp.getHostToken(); + } +} +export function getEntityInfo(identity) { + return coreState.getEntityInfo(identity); +} +export function getEnvironmentVariable(varsToExpand) { + if (Array.isArray(varsToExpand)) { + return varsToExpand.reduce(function(result, envVar) { + result[envVar] = process.env[envVar] || null; + return result; + }, {}); + } else { + return process.env[varsToExpand] || null; + } +} +export function getFocusedWindow() { + const { id } = electronBrowserWindow.getFocusedWindow() || {}; + const { uuid, name } = coreState.getWinObjById(id) || {}; + return uuid ? { uuid, name } : null; +} +export function getFocusedExternalWindow() { + let { uuid } = electronBrowserWindow.getFocusedWindow() || {}; + return uuid ? { uuid } : null; +} +export function getHostSpecs() { + let state = new IdleState(); + const theme = (process.platform === 'win32') ? { aeroGlassEnabled: electronApp.isAeroGlassEnabled() } : {}; + return Object.assign({ + cpus: os.cpus(), + memory: os.totalmem(), + name: electronApp.getSystemName(), + arch: electronApp.getSystemArch(), + gpu: { + name: electronApp.getGpuName() + }, + screenSaver: state.isScreenSaverRunning(), + }, theme); +} +export function getInstalledRuntimes(identity, callback, errorCallback) { + var getInstalledRuntimesOpts = { + uuid: identity.uuid, + sourceUrl: coreState.getConfigUrlByUuid(identity.uuid) + }; + + var handleResponse = function(dataObj) { + var failed = _.has(dataObj, 'time-to-live-expiration'); + if (!failed) { + callback(dataObj.payload); } else { - const hash = crypto.createHash('sha256'); - - const macAddress = os.networkInterfaces().en0[0].mac; - if (!macAddress) { - throw new Error(`MAC address (${macAddress}) not defined`); - } - - hash.update(macAddress); - return hash.digest('hex'); + errorCallback(dataObj.payload); } - }, - getEntityInfo: function(identity) { - return coreState.getEntityInfo(identity); - }, - getEnvironmentVariable: function(varsToExpand) { - if (Array.isArray(varsToExpand)) { - return varsToExpand.reduce(function(result, envVar) { - result[envVar] = process.env[envVar] || null; - return result; - }, {}); + }; + + rvmBus.getInstalledRuntimes(getInstalledRuntimesOpts, handleResponse); +} +export function getLog(name, resolve) { + // Prevent abuse of trying to read files with a path relative to cache directory + var pathSafeName = path.basename(name); + if (pathSafeName === name) { + var pattern = /^debug.*\.log$/; + if (pattern.test(pathSafeName)) { + fs.readFile(electronApp.getPath('userCache') + '/' + pathSafeName, { + encoding: 'utf8' + }, (err, data) => { + if (!err) { + resolve(undefined, data); + } else { + resolve(`Could not read log file ${name}`); + } + }); } else { - return process.env[varsToExpand] || null; + resolve(`${name} is not a valid log file.`); } - }, - getFocusedWindow: function() { - const { id } = electronBrowserWindow.getFocusedWindow() || {}; - const { uuid, name } = coreState.getWinObjById(id) || {}; - return uuid ? { uuid, name } : null; - }, - getFocusedExternalWindow: function() { - let { uuid } = electronBrowserWindow.getFocusedWindow() || {}; - return uuid ? { uuid } : null; - }, - getHostSpecs: function() { - let state = new IdleState(); - const theme = (process.platform === 'win32') ? { aeroGlassEnabled: electronApp.isAeroGlassEnabled() } : {}; - return Object.assign({ - cpus: os.cpus(), - memory: os.totalmem(), - name: electronApp.getSystemName(), - arch: electronApp.getSystemArch(), - gpu: { - name: electronApp.getGpuName() - }, - screenSaver: state.isScreenSaverRunning(), - }, theme); - }, - getInstalledRuntimes: function(identity, callback, errorCallback) { - var getInstalledRuntimesOpts = { - uuid: identity.uuid, - sourceUrl: coreState.getConfigUrlByUuid(identity.uuid) - }; + } else { + resolve('Only log file in the base cache directory are supported.'); + } +} +export function getLogList(callback, options) { + fs.readdir(electronApp.getPath('userCache'), function(err, files) { + let opts = options || {}; + + if (!err) { + let pattern = opts.pattern || /^debug+(\w)*\.log$/; + var logFiles = _.filter(files, fileName => { + return pattern.test(fileName); + }); - var handleResponse = function(dataObj) { - var failed = _.has(dataObj, 'time-to-live-expiration'); - if (!failed) { - callback(dataObj.payload); - } else { - errorCallback(dataObj.payload); - } - }; - rvmBus.getInstalledRuntimes(getInstalledRuntimesOpts, handleResponse); - }, - getLog: function(name, resolve) { - // Prevent abuse of trying to read files with a path relative to cache directory - var pathSafeName = path.basename(name); - if (pathSafeName === name) { - var pattern = /^debug.*\.log$/; - if (pattern.test(pathSafeName)) { - fs.readFile(electronApp.getPath('userCache') + '/' + pathSafeName, { - encoding: 'utf8' - }, (err, data) => { - if (!err) { - resolve(undefined, data); - } else { - resolve(`Could not read log file ${name}`); - } - }); - } else { - resolve(`${name} is not a valid log file.`); - } - } else { - resolve('Only log file in the base cache directory are supported.'); - } - }, - getLogList: function(callback, options) { - fs.readdir(electronApp.getPath('userCache'), function(err, files) { - let opts = options || {}; - - if (!err) { - let pattern = opts.pattern || /^debug+(\w)*\.log$/; - var logFiles = _.filter(files, fileName => { - return pattern.test(fileName); - }); + var fileStats = []; + if (logFiles.length) { + var index = 0; + var processFileStats = function() { + var name = logFiles[index++]; - var fileStats = []; - if (logFiles.length) { - var index = 0; + fs.stat(electronApp.getPath('userCache') + '/' + name, (err, stats) => { + if (!err) { + fileStats.push({ + name: name, + size: stats.size, + date: stats.mtime + }); + } - var processFileStats = function() { - var name = logFiles[index++]; - - fs.stat(electronApp.getPath('userCache') + '/' + name, (err, stats) => { - if (!err) { - fileStats.push({ - name: name, - size: stats.size, - date: stats.mtime - }); + if (index < logFiles.length) { + processFileStats(); + } else { + if (typeof callback === 'function') { + callback(undefined, fileStats); } + } + // } else if (typeof callback === 'function') { + // callback('An error occured while trying to retrieve log information: ' + err); + // } + }); + }; - if (index < logFiles.length) { - processFileStats(); - } else { - if (typeof callback === 'function') { - callback(undefined, fileStats); - } - } - // } else if (typeof callback === 'function') { - // callback('An error occured while trying to retrieve log information: ' + err); - // } - }); - }; - - processFileStats(); - } else if (typeof callback === 'function') { - callback(undefined, fileStats); - } + processFileStats(); } else if (typeof callback === 'function') { - callback('Could not locate any log files'); + callback(undefined, fileStats); } - }); - }, - getMachineId: function() { - if (process.platform === 'win32') { - const registryInfo = this.readRegistryValue('HKEY_LOCAL_MACHINE', 'SOFTWARE\\Microsoft\\Cryptography', 'MachineGuid'); - return registryInfo.data; - } else if (process.platform === 'darwin') { - // This is implemented at the native level, as we need to access OS X-specific API functions. - return electronApp.getMachineId(); - } else { - return ''; + } else if (typeof callback === 'function') { + callback('Could not locate any log files'); } - }, - getMinLogLevel: function() { - try { - const logLevel = electronApp.getMinLogLevel(); - - return log.logLevelMappings.get(logLevel); - } catch (e) { - return e; - } - }, - getMonitorInfo: function() { - return MonitorInfo.getInfo('api-query'); - }, - getMousePosition: function() { - return MonitorInfo.getMousePosition(); - }, - getProcessList: function() { - - let allApps = coreState.getAllApplications(); - let runningAps = allApps.filter(app => { - return app.isRunning; - }); - - let processList = runningAps.map(app => { - var appObj = coreState.getAppObjByUuid(app.uuid), - name = appObj._options.name, - proc = appObj._processInfo || defaultProc; - - return { - cpuUsage: proc.getCpuUsage(), - name: name, - nonPagedPoolUsage: proc.getNonPagedPoolUsage(), - pageFaultCount: proc.getPageFaultCount(), - pagedPoolUsage: proc.getPagedPoolUsage(), - pagefileUsage: proc.getPagefileUsage(), - peakNonPagedPoolUsage: proc.getPeakNonPagedPoolUsage(), - peakPagedPoolUsage: proc.getPeakPagedPoolUsage(), - peakPagefileUsage: proc.getPeakPagefileUsage(), - peakWorkingSetSize: proc.getPeakWorkingSetSize(), - processId: appObj.mainWindow.webContents.processId, - uuid: appObj.uuid, - workingSetSize: proc.getWorkingSetSize() - }; - }); + }); +} +export function getMachineId() { + if (process.platform === 'win32') { + const registryInfo = this.readRegistryValue('HKEY_LOCAL_MACHINE', 'SOFTWARE\\Microsoft\\Cryptography', 'MachineGuid'); + return registryInfo.data; + } else if (process.platform === 'darwin') { + // This is implemented at the native level, as we need to access OS X-specific API functions. + return electronApp.getMachineId(); + } else { + return ''; + } +} +export function getMinLogLevel() { + try { + const logLevel = electronApp.getMinLogLevel(); + + return logger.logLevelMappings.get(logLevel); + } catch (e) { + return e; + } +} +export function getMonitorInfo() { + return MonitorInfo.getInfo('api-query'); +} +export function getMousePosition() { + return MonitorInfo.getMousePosition(); +} +export function getProcessList() { + + let allApps = coreState.getAllApplications(); + let runningAps = allApps.filter(app => { + return app.isRunning; + }); - return processList; - }, + let processList = runningAps.map(app => { + var appObj = coreState.getAppObjByUuid(app.uuid), + name = appObj._options.name, + proc = appObj._processInfo || defaultProc; - getProxySettings: function() { return { - config: coreState.getManifestProxySettings(), - system: session.defaultSession.getProxySettings() - }; - }, - getRemoteConfig: function(url, callback, errorCallback) { - fetchReadFile(url, true) - .then(callback) - .catch(errorCallback); - }, - getVersion: function() { - return process.versions['openfin']; - }, - getRuntimeInfo: function(identity) { - const { port, securityRealm, version } = - portDiscovery.getPortInfoByArgs(coreState.argo, socketServer.getPort()); - const manifestUrl = coreState.getConfigUrlByUuid(identity.uuid); - const architecture = process.arch; - const cachePath = electronApp.getPath('userData'); - const args = Object.assign({}, coreState.argo); - args._ = undefined; - return { manifestUrl, port, securityRealm, version, architecture, cachePath, args }; - }, - getRvmInfo: function(identity, callback, errorCallback) { - let appObject = coreState.getAppObjByUuid(identity.uuid); - let sourceUrl = (appObject || {})._configUrl || ''; - - // TODO: Move this require to the top of file during future 'dependency injection refactor' - // Must require here otherwise runtime error Cannot create browser window before app is ready - let RvmInfoFetcher = require('../rvm/runtime_initiated_topics/rvm_info.js').default; - RvmInfoFetcher.fetch(sourceUrl, callback, errorCallback); - }, - getServiceConfiguration: function() { - const rvmMessage = { - topic: 'application', - action: 'get-service-settings', - sourceUrl: 'https://openfin.co' + cpuUsage: proc.getCpuUsage(), + name: name, + nonPagedPoolUsage: proc.getNonPagedPoolUsage(), + pageFaultCount: proc.getPageFaultCount(), + pagedPoolUsage: proc.getPagedPoolUsage(), + pagefileUsage: proc.getPagefileUsage(), + peakNonPagedPoolUsage: proc.getPeakNonPagedPoolUsage(), + peakPagedPoolUsage: proc.getPeakPagedPoolUsage(), + peakPagefileUsage: proc.getPeakPagefileUsage(), + peakWorkingSetSize: proc.getPeakWorkingSetSize(), + processId: appObj.mainWindow.webContents.processId, + uuid: appObj.uuid, + workingSetSize: proc.getWorkingSetSize() }; + }); - return new Promise((resolve) => { - rvmBus.publish(rvmMessage, response => { - if (!response || !response.payload) { - resolve(new Error('Bad Response from RVM')); - } else if (response.payload.success === false) { - resolve(new Error(response.payload.error || 'get-service-settings failed')); - } else { - resolve(response.payload.settings); - } - }); - }); - }, - launchExternalProcess: function(identity, options, errDataCallback) { // Node-style callback used here - options.srcUrl = coreState.getConfigUrlByUuid(identity.uuid); - - ProcessTracker.launch(identity, options, errDataCallback); - }, - monitorExternalProcess: function(identity, options, callback, errorCallback) { - const payload = ProcessTracker.monitor(identity, Object.assign({ - monitor: true - }, options)); - - if (payload) { - callback(payload); - } else { - errorCallback('Error monitoring external process, pid: ' + options.pid); - } - }, - log: function(level, message) { - return log.writeToLog(level, message, false); - }, - setMinLogLevel: function(level) { - try { - const levelAsString = String(level); // We only accept log levels as strings here - const mappedLevel = log.logLevelMappings.get(levelAsString); - - if (mappedLevel === undefined) { - throw new Error(`Invalid logging level: ${level}`); + return processList; +} + +export function getProxySettings() { + return { + config: coreState.getManifestProxySettings(), + system: session.defaultSession.getProxySettings() + }; +} +export function getRemoteConfig(url, callback, errorCallback) { + fetchReadFile(url, true) + .then(callback) + .catch(errorCallback); +} +export function getVersion() { + return process.versions['openfin']; +} +export function getRuntimeInfo(identity) { + const { port, securityRealm, version } = + portDiscovery.getPortInfoByArgs(coreState.argo, socketServer.getPort()); + const manifestUrl = coreState.getConfigUrlByUuid(identity.uuid); + const architecture = process.arch; + const cachePath = electronApp.getPath('userData'); + const args = Object.assign({}, coreState.argo); + args._ = undefined; + return { manifestUrl, port, securityRealm, version, architecture, cachePath, args }; +} +export function getRvmInfo(identity, callback, errorCallback) { + let appObject = coreState.getAppObjByUuid(identity.uuid); + let sourceUrl = (appObject || {})._configUrl || ''; + + // TODO: Move this require to the top of file during future 'dependency injection refactor' + // Must require here otherwise runtime error Cannot create browser window before app is ready + let RvmInfoFetcher = require('../rvm/runtime_initiated_topics/rvm_info.js').default; + RvmInfoFetcher.fetch(sourceUrl, callback, errorCallback); +} +export function getServiceConfiguration() { + const rvmMessage = { + topic: 'application', + action: 'get-service-settings', + sourceUrl: 'https://openfin.co' + }; + + return new Promise((resolve) => { + rvmBus.publish(rvmMessage, response => { + if (!response || !response.payload) { + resolve(new Error('Bad Response from RVM')); + } else if (response.payload.success === false) { + resolve(new Error(response.payload.error || 'get-service-settings failed')); + } else { + resolve(response.payload.settings); } - electronApp.setMinLogLevel(mappedLevel); - } catch (e) { - return e; - } - }, - debugLog: function(level, message) { - return log.writeToLog(level, message, true); - }, - openUrlWithBrowser: function(url) { - shell.openExternal(url); - }, - readRegistryValue: function(rootKey, subkey, value) { - const registryPayload = electronApp.readRegistryValue(rootKey, subkey, value); - - if (registryPayload && registryPayload.error) { - throw new Error(registryPayload.error); + }); + }); +} +export function launchExternalProcess(identity, options, errDataCallback) { // Node-style callback used here + options.srcUrl = coreState.getConfigUrlByUuid(identity.uuid); + + ProcessTracker.launch(identity, options, errDataCallback); +} +export function monitorExternalProcess(identity, options, callback, errorCallback) { + const payload = ProcessTracker.monitor(identity, Object.assign({ + monitor: true + }, options)); + + if (payload) { + callback(payload); + } else { + errorCallback('Error monitoring external process, pid: ' + options.pid); + } +} +export function log(level, message) { + return logger.writeToLog(level, message, false); +} +export function setMinLogLevel(level) { + try { + const levelAsString = String(level); // We only accept log levels as strings here + const mappedLevel = logger.logLevelMappings.get(levelAsString); + + if (mappedLevel === undefined) { + throw new Error(`Invalid logging level: ${level}`); } + electronApp.setMinLogLevel(mappedLevel); + } catch (e) { + return e; + } +} +export function debugLog(level, message) { + return logger.writeToLog(level, message, true); +} +export function openUrlWithBrowser(url) { + shell.openExternal(url); +} +export function readRegistryValue(rootKey, subkey, value) { + const registryPayload = electronApp.readRegistryValue(rootKey, subkey, value); + + if (registryPayload && registryPayload.error) { + throw new Error(registryPayload.error); + } - return registryPayload; - }, - releaseExternalProcess: function(processUuid) { - ProcessTracker.release(processUuid); - }, - removeEventListener: function(type, listener) { - ofEvents.removeListener(route.system(type), listener); - }, - showDeveloperTools: function(applicationUuid, windowName) { - let winName, openfinWindow; + return registryPayload; +} +export function releaseExternalProcess(processUuid) { + ProcessTracker.release(processUuid); +} +export function removeEventListener(type, listener) { + ofEvents.removeListener(route.system(type), listener); +} +export function showDeveloperTools(applicationUuid, windowName) { + let winName, openfinWindow; + + if (!windowName) { + winName = applicationUuid; + } else { + winName = windowName; + } - if (!windowName) { - winName = applicationUuid; - } else { - winName = windowName; - } + openfinWindow = coreState.getWindowByUuidName(applicationUuid, winName); - openfinWindow = coreState.getWindowByUuidName(applicationUuid, winName); + if (openfinWindow && openfinWindow.browserWindow) { + openfinWindow.browserWindow.openDevTools(); + } +} + +export function showChromeNotificationCenter() {} +export function startCrashReporter(identity, options) { + const configUrl = coreState.argo['startup-url'] || coreState.argo['config']; + const reporterOptions = Object.assign({ configUrl }, options); + + logger.setToVerbose(); + return crashReporter.startOFCrashReporter(reporterOptions); +} +export function terminateExternalProcess(processUuid, timeout = 3000, child = false) { + let status = ProcessTracker.terminate(processUuid, timeout, child); + + let result; + if (status === 0) { + result = 'failed'; + } else if (status === 1) { + result = 'clean'; + } else { + result = 'terminated'; + } - if (openfinWindow && openfinWindow.browserWindow) { - openfinWindow.browserWindow.openDevTools(); - } - }, + return { + result + }; +} +export function updateProxySettings(type, proxyAddress, proxyPort) { + return coreState.setManifestProxySettings({ + type: type, + proxyAddress: proxyAddress, + proxyPort: proxyPort + }); +} +export function setCookie(opts, callback, errorCallback) { + //OpenFin ttl = 0 means the cookie should live forever. + // 5.0 Defaults to live forever even in the absence of ttl being defined + let timeToLive = -1; + if (typeof opts.ttl === 'number' && opts.ttl !== 0) { + timeToLive = opts.ttl / 1000; + } - showChromeNotificationCenter: function() {}, - startCrashReporter: function(identity, options) { - const configUrl = coreState.argo['startup-url'] || coreState.argo['config']; - const reporterOptions = Object.assign({ configUrl }, options); + //Expand the OpenFin cookie shape to Electron cookie shape. + //If an Electron cookie shape is passed then it is used. + //https://github.com/openfin/runtime/blob/develop/docs/api/session.md#sescookiessetdetails-callback + opts.expirationDate = Date.now() + timeToLive; + opts.session = opts.session ? opts.session : opts.httpOnly; - log.setToVerbose(); - return crashReporter.startOFCrashReporter(reporterOptions); - }, - terminateExternalProcess: function(processUuid, timeout = 3000, child = false) { - let status = ProcessTracker.terminate(processUuid, timeout, child); - - let result; - if (status === 0) { - result = 'failed'; - } else if (status === 1) { - result = 'clean'; + session.defaultSession.cookies.set(opts, function(error) { + if (!error) { + callback(); } else { - result = 'terminated'; + errorCallback(error); } - - return { - result - }; - }, - updateProxySettings: function(type, proxyAddress, proxyPort) { - return coreState.setManifestProxySettings({ - type: type, - proxyAddress: proxyAddress, - proxyPort: proxyPort - }); - }, - setCookie: function(opts, callback, errorCallback) { - //OpenFin ttl = 0 means the cookie should live forever. - // 5.0 Defaults to live forever even in the absence of ttl being defined - let timeToLive = -1; - if (typeof opts.ttl === 'number' && opts.ttl !== 0) { - timeToLive = opts.ttl / 1000; - } - - //Expand the OpenFin cookie shape to Electron cookie shape. - //If an Electron cookie shape is passed then it is used. - //https://github.com/openfin/runtime/blob/develop/docs/api/session.md#sescookiessetdetails-callback - opts.expirationDate = Date.now() + timeToLive; - opts.session = opts.session ? opts.session : opts.httpOnly; - - session.defaultSession.cookies.set(opts, function(error) { - if (!error) { - callback(); - } else { + }); +} +export function getCookies(opts, callback, errorCallback) { + const { url, name } = opts; + if (url && url.length > 0 && name && name.length > 0) { + session.defaultSession.cookies.get({ url, name }, (error, cookies) => { + if (error) { + logger.writeToLog(1, `cookies.get error ${error}`, true); errorCallback(error); - } - }); - }, - getCookies: function(opts, callback, errorCallback) { - const { url, name } = opts; - if (url && url.length > 0 && name && name.length > 0) { - session.defaultSession.cookies.get({ url, name }, (error, cookies) => { - if (error) { - log.writeToLog(1, `cookies.get error ${error}`, true); - errorCallback(error); - } else if (cookies.length > 0) { - const data = - cookies.filter(cookie => !cookie.httpOnly).map(cookie => { - return { - name: cookie.name, - expirationDate: cookie.expirationDate, - path: cookie.path, - domain: cookie.domain - }; - }); - log.writeToLog(1, `cookies filtered ${data.length}`, true); - if (data.length > 0) { - callback(data); - } else { - errorCallback(`Cookie not found ${name}`); - } + } else if (cookies.length > 0) { + const data = + cookies.filter(cookie => !cookie.httpOnly).map(cookie => { + return { + name: cookie.name, + expirationDate: cookie.expirationDate, + path: cookie.path, + domain: cookie.domain + }; + }); + logger.writeToLog(1, `cookies filtered ${data.length}`, true); + if (data.length > 0) { + callback(data); } else { - log.writeToLog(1, `cookies result ${cookies.length}`, true); errorCallback(`Cookie not found ${name}`); } - }); + } else { + logger.writeToLog(1, `cookies result ${cookies.length}`, true); + errorCallback(`Cookie not found ${name}`); + } + }); + } else { + errorCallback(`Error getting cookies`); + } +} +export function flushCookieStore(callback) { + session.defaultSession.cookies.flushStore(callback); +} +export function generateGUID() { + return electronApp.generateGUID(); +} +export function convertOptions(options) { + return optionsConverter.convertToElectron(options); +} +export function getNearestDisplayRoot(point) { + return MonitorInfo.getNearestDisplayRoot(point); +} +export function raiseEvent(eventName, eventArgs) { + return ofEvents.emit(eventName, eventArgs); +} +// eventsIter is an Array or other iterable object (such as a Map or Set) +// whose elements are [key, value] pairs when iterated over +export function raiseManyEvents(eventsIter) { + + for (let [eventName, args] of eventsIter) { + ofEvents.emit(eventName, args); + } +} +export function downloadAsset(identity, asset, cb) { + const srcUrl = coreState.getConfigUrlByUuid(identity.uuid); + const downloadId = asset.downloadId; + + //setup defaults. + asset.args = asset.args || ''; + + const rvmMessage = { + topic: 'app-assets', + type: 'download-asset', + appConfig: srcUrl, + showRvmProgressDialog: false, + asset: asset, + downloadId: downloadId + }; + + const publishSuccess = rvmBus.publish(rvmMessage, response => { + if (response.error) { + cb(new Error(response.error)); } else { - errorCallback(`Error getting cookies`); + cb(); } - }, - flushCookieStore: function(callback) { - session.defaultSession.cookies.flushStore(callback); - }, - generateGUID: function() { - return electronApp.generateGUID(); - }, - convertOptions: function(options) { - return convertOptions.convertToElectron(options); - }, - getNearestDisplayRoot: function(point) { - return MonitorInfo.getNearestDisplayRoot(point); - }, - raiseEvent: function(eventName, eventArgs) { - return ofEvents.emit(eventName, eventArgs); - }, - // eventsIter is an Array or other iterable object (such as a Map or Set) - // whose elements are [key, value] pairs when iterated over - raiseManyEvents: function(eventsIter) { + }); - for (let [eventName, args] of eventsIter) { - ofEvents.emit(eventName, args); - } - }, - downloadAsset: function(identity, asset, cb) { - const srcUrl = coreState.getConfigUrlByUuid(identity.uuid); - const downloadId = asset.downloadId; - - //setup defaults. - asset.args = asset.args || ''; - - const rvmMessage = { - topic: 'app-assets', - type: 'download-asset', - appConfig: srcUrl, - showRvmProgressDialog: false, - asset: asset, - downloadId: downloadId - }; + if (!publishSuccess) { + cb(new Error('RVM Message failed.')); + } +} - const publishSuccess = rvmBus.publish(rvmMessage, response => { - if (response.error) { - cb(new Error(response.error)); - } else { - cb(); - } - }); +export function downloadRuntime(identity, options, cb) { + options.sourceUrl = coreState.getConfigUrlByUuid(identity.uuid); + rvmBus.downloadRuntime(options, cb); - if (!publishSuccess) { - cb(new Error('RVM Message failed.')); +} +export function getAllExternalApplications() { + return ExternalApplication.getAllExternalConnctions().map(eApp => { + return { + uuid: eApp.uuid + }; + }); +} +export function getAllExternalWindows() { + const skipOpenFinWindows = true; + const allNativeWindows = electronApp.getAllNativeWindowInfo(skipOpenFinWindows); + const externalWindows = []; + + allNativeWindows.forEach(e => { + const externalWindow = getNativeWindowInfoLite(e); + const isValid = isValidExternalWindow(e); + + if (isValid) { + externalWindows.push(externalWindow); } - }, + }); - downloadRuntime: function(identity, options, cb) { - options.sourceUrl = coreState.getConfigUrlByUuid(identity.uuid); - rvmBus.downloadRuntime(options, cb); + return externalWindows; +} +export function resolveUuid(identity, uuid, cb) { + const externalConn = ExternalApplication.getAllExternalConnctions().find(c => c.uuid === uuid); + const app = coreState.getAppObjByUuid(uuid); - }, - getAllExternalApplications: function() { - return ExternalApplication.getAllExternalConnctions().map(eApp => { - return { - uuid: eApp.uuid - }; + if (externalConn) { + cb(null, { + type: 'external-app', + uuid: externalConn.uuid }); - }, - getAllExternalWindows: function() { - const skipOpenFinWindows = true; - const allNativeWindows = electronApp.getAllNativeWindowInfo(skipOpenFinWindows); - const externalWindows = []; - - allNativeWindows.forEach(e => { - const externalWindow = getNativeWindowInfoLite(e); - const isValid = isValidExternalWindow(e); - - if (isValid) { - externalWindows.push(externalWindow); - } + } else if (app) { + cb(null, { + type: 'application', + uuid: app.uuid }); + } else { + cb(new Error('uuid not found.')); + } +} - return externalWindows; - }, - resolveUuid: function(identity, uuid, cb) { - const externalConn = ExternalApplication.getAllExternalConnctions().find(c => c.uuid === uuid); - const app = coreState.getAppObjByUuid(uuid); - - if (externalConn) { - cb(null, { - type: 'external-app', - uuid: externalConn.uuid - }); - } else if (app) { - cb(null, { - type: 'application', - uuid: app.uuid - }); - } else { - cb(new Error('uuid not found.')); - } - }, - - downloadPreloadScripts: function(identity, preloadScripts) { - return downloadScripts(identity, preloadScripts); - }, +export function downloadPreloadScripts(identity, preloadScripts) { + return downloadScripts(identity, preloadScripts); +} - getPreloadScripts: function(identity) { - return loadScripts(identity); - } +export function getPreloadScripts(identity) { + return loadScripts(identity); +} +export const System = { + addEventListener, + authenticateResourceFetch, + clearCache, + createProxySocket, + authenticateProxySocket, + deleteCacheOnExit, + exit, + getAllWindows, + getAllApplications, + getAppAssetInfo, + getCommandLineArguments, + getConfig, + getCrashReporterState, + getDeviceUserId, + getDeviceId, + getEntityInfo, + getEnvironmentVariable, + getFocusedWindow, + getFocusedExternalWindow, + getHostSpecs, + getInstalledRuntimes, + getLog, + getLogList, + getMachineId, + getMinLogLevel, + getMonitorInfo, + getMousePosition, + getProcessList, + getProxySettings, + getRemoteConfig, + getVersion, + getRuntimeInfo, + getRvmInfo, + getServiceConfiguration, + launchExternalProcess, + monitorExternalProcess, + log, + setMinLogLevel, + debugLog, + openUrlWithBrowser, + readRegistryValue, + releaseExternalProcess, + removeEventListener, + showDeveloperTools, + showChromeNotificationCenter, + startCrashReporter, + terminateExternalProcess, + updateProxySettings, + setCookie, + getCookies, + flushCookieStore, + generateGUID, + convertOptions, + getNearestDisplayRoot, + raiseEvent, + raiseManyEvents, + downloadAsset, + downloadRuntime, + getAllExternalApplications, + getAllExternalWindows, + resolveUuid, + downloadPreloadScripts, + getPreloadScripts };