Skip to content

Commit 1aaf1a8

Browse files
committed
Merge branch 'update'
2 parents 603e08d + 072c0ae commit 1aaf1a8

11 files changed

Lines changed: 561 additions & 424 deletions

File tree

src/vs/code/electron-main/main.ts

Lines changed: 107 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import { WindowsService } from 'vs/platform/windows/electron-main/windowsService
2020
import { WindowEventChannel } from 'vs/code/common/windowsIpc';
2121
import { ILifecycleService, LifecycleService } from 'vs/code/electron-main/lifecycle';
2222
import { VSCodeMenu } from 'vs/code/electron-main/menus';
23-
import { IUpdateService, UpdateManager } from 'vs/code/electron-main/update-manager';
23+
import { IUpdateService } from 'vs/platform/update/common/update';
24+
import { UpdateChannel } from 'vs/platform/update/common/updateIpc';
25+
import { UpdateService } from 'vs/platform/update/electron-main/updateService';
2426
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
2527
import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net';
2628
import { TPromise } from 'vs/base/common/winjs.base';
@@ -46,8 +48,13 @@ import { getPathLabel } from 'vs/base/common/labels';
4648
import { IURLService } from 'vs/platform/url/common/url';
4749
import { URLChannel } from 'vs/platform/url/common/urlIpc';
4850
import { URLService } from 'vs/platform/url/electron-main/urlService';
51+
import { ITelemetryService, NullTelemetryService } from 'vs/platform/telemetry/common/telemetry';
52+
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
53+
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
54+
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
55+
import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
4956
import product from 'vs/platform/product';
50-
57+
import pkg from 'vs/platform/package';
5158
import * as fs from 'original-fs';
5259
import * as cp from 'child_process';
5360
import * as path from 'path';
@@ -72,13 +79,13 @@ function quit(accessor: ServicesAccessor, arg?: any) {
7279
process.exit(exitCode); // in main, process.exit === app.exit
7380
}
7481

82+
// TODO@Joao wow this is huge, clean up!
7583
function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platform.IProcessEnvironment): void {
7684
const instantiationService = accessor.get(IInstantiationService);
7785
const logService = accessor.get(ILogService);
7886
const environmentService = accessor.get(IEnvironmentService);
7987
const windowsMainService = accessor.get(IWindowsMainService);
8088
const lifecycleService = accessor.get(ILifecycleService);
81-
const updateService = accessor.get(IUpdateService);
8289
const configurationService = accessor.get(IConfigurationService) as ConfigurationService<any>;
8390
const windowEventChannel = new WindowEventChannel(windowsMainService);
8491

@@ -147,82 +154,107 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
147154

148155
let sharedProcessDisposable;
149156

150-
spawnSharedProcess(initData, options).done(disposable => {
157+
const sharedProcess = spawnSharedProcess(initData, options).then(disposable => {
151158
sharedProcessDisposable = disposable;
152-
153-
connect(environmentService.sharedIPCHandle, 'main')
154-
.done(client => client.registerChannel('windowEvent', windowEventChannel));
159+
return connect(environmentService.sharedIPCHandle, 'main');
155160
});
156161

157-
// Make sure we associate the program with the app user model id
158-
// This will help Windows to associate the running program with
159-
// any shortcut that is pinned to the taskbar and prevent showing
160-
// two icons in the taskbar for the same app.
161-
if (platform.isWindows && product.win32AppUserModelId) {
162-
app.setAppUserModelId(product.win32AppUserModelId);
162+
// Create a new service collection, because the telemetry service
163+
// requires a connection to shared process, which was only established
164+
// now.
165+
const services = new ServiceCollection();
166+
services.set(IUpdateService, new SyncDescriptor(UpdateService));
167+
168+
if (environmentService.isBuilt && !environmentService.extensionDevelopmentPath && !!product.enableTelemetry) {
169+
const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
170+
const appender = new TelemetryAppenderClient(channel);
171+
const commonProperties = resolveCommonProperties(product.commit, pkg.version);
172+
const piiPaths = [environmentService.appRoot, environmentService.extensionsPath];
173+
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths };
174+
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config));
175+
} else {
176+
services.set(ITelemetryService, NullTelemetryService);
163177
}
164178

165-
function dispose() {
166-
if (mainIpcServer) {
167-
mainIpcServer.dispose();
168-
mainIpcServer = null;
169-
}
179+
const instantiationService2 = instantiationService.createChild(services);
170180

171-
if (sharedProcessDisposable) {
172-
sharedProcessDisposable.dispose();
173-
}
181+
instantiationService2.invokeFunction(accessor => {
182+
// Register more Electron IPC services
183+
const updateService = accessor.get(IUpdateService);
184+
const updateChannel = new UpdateChannel(updateService);
185+
electronIpcServer.registerChannel('update', updateChannel);
186+
187+
// Register windowEvent
188+
sharedProcess.done(client => client.registerChannel('windowEvent', windowEventChannel));
174189

175-
if (windowsMutex) {
176-
windowsMutex.release();
190+
// Make sure we associate the program with the app user model id
191+
// This will help Windows to associate the running program with
192+
// any shortcut that is pinned to the taskbar and prevent showing
193+
// two icons in the taskbar for the same app.
194+
if (platform.isWindows && product.win32AppUserModelId) {
195+
app.setAppUserModelId(product.win32AppUserModelId);
177196
}
178197

179-
configurationService.dispose();
180-
}
198+
function dispose() {
199+
if (mainIpcServer) {
200+
mainIpcServer.dispose();
201+
mainIpcServer = null;
202+
}
181203

182-
// Dispose on app quit
183-
app.on('will-quit', () => {
184-
logService.log('App#will-quit: disposing resources');
204+
if (sharedProcessDisposable) {
205+
sharedProcessDisposable.dispose();
206+
}
185207

186-
dispose();
187-
});
208+
if (windowsMutex) {
209+
windowsMutex.release();
210+
}
188211

189-
// Dispose on vscode:exit
190-
ipc.on('vscode:exit', (event, code: number) => {
191-
logService.log('IPC#vscode:exit', code);
212+
configurationService.dispose();
213+
}
192214

193-
dispose();
194-
process.exit(code); // in main, process.exit === app.exit
195-
});
215+
// Dispose on app quit
216+
app.on('will-quit', () => {
217+
logService.log('App#will-quit: disposing resources');
196218

197-
// Lifecycle
198-
lifecycleService.ready();
219+
dispose();
220+
});
199221

200-
// Propagate to clients
201-
windowsMainService.ready(userEnv);
222+
// Dispose on vscode:exit
223+
ipc.on('vscode:exit', (event, code: number) => {
224+
logService.log('IPC#vscode:exit', code);
202225

203-
// Install Menu
204-
const menu = instantiationService.createInstance(VSCodeMenu);
205-
menu.ready();
226+
dispose();
227+
process.exit(code); // in main, process.exit === app.exit
228+
});
206229

207-
// Install JumpList on Windows (keep updated when windows open)
208-
if (platform.isWindows) {
209-
updateJumpList(windowsMainService, logService);
210-
windowsMainService.onOpen(() => updateJumpList(windowsMainService, logService));
211-
}
230+
// Lifecycle
231+
lifecycleService.ready();
212232

213-
// Setup auto update
214-
updateService.initialize();
233+
// Propagate to clients
234+
windowsMainService.ready(userEnv);
215235

216-
// Open our first window
217-
if (environmentService.args['new-window'] && environmentService.args._.length === 0) {
218-
windowsMainService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true }); // new window if "-n" was used without paths
219-
} else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) {
220-
windowsMainService.open({ cli: environmentService.args, pathsToOpen: global.macOpenFiles }); // mac: open-file event received on startup
221-
} else {
222-
windowsMainService.open({ cli: environmentService.args, forceNewWindow: environmentService.args['new-window'], diffMode: environmentService.args.diff }); // default: read paths from cli
223-
}
236+
// Install Menu
237+
const menu = instantiationService2.createInstance(VSCodeMenu);
238+
menu.ready();
239+
240+
// Install JumpList on Windows (keep updated when windows open)
241+
if (platform.isWindows) {
242+
updateJumpList(windowsMainService, logService);
243+
windowsMainService.onOpen(() => updateJumpList(windowsMainService, logService));
244+
}
245+
246+
// Open our first window
247+
if (environmentService.args['new-window'] && environmentService.args._.length === 0) {
248+
windowsMainService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true }); // new window if "-n" was used without paths
249+
} else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) {
250+
windowsMainService.open({ cli: environmentService.args, pathsToOpen: global.macOpenFiles }); // mac: open-file event received on startup
251+
} else {
252+
windowsMainService.open({ cli: environmentService.args, forceNewWindow: environmentService.args['new-window'], diffMode: environmentService.args.diff }); // default: read paths from cli
253+
}
254+
});
224255
}
225256

257+
// TODO@Joao TODO@Ben shouldn't this be inside windows service instead?
226258
function updateJumpList(windowsMainService: IWindowsMainService, logService: ILogService): void {
227259
const jumpList: Electron.JumpListCategory[] = [];
228260

@@ -448,19 +480,7 @@ function createPaths(environmentService: IEnvironmentService): TPromise<any> {
448480
return TPromise.join(paths.map(p => mkdirp(p))) as TPromise<any>;
449481
}
450482

451-
function start(): void {
452-
let args: ParsedArgs;
453-
454-
try {
455-
args = parseMainProcessArgv(process.argv);
456-
args = validatePaths(args);
457-
} catch (err) {
458-
console.error(err.message);
459-
process.exit(1);
460-
return;
461-
}
462-
463-
// TODO: isolate
483+
function createServices(args): IInstantiationService {
464484
const services = new ServiceCollection();
465485

466486
services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, args, process.execPath));
@@ -471,10 +491,24 @@ function start(): void {
471491
services.set(IStorageService, new SyncDescriptor(StorageService));
472492
services.set(IConfigurationService, new SyncDescriptor(ConfigurationService));
473493
services.set(IRequestService, new SyncDescriptor(RequestService));
474-
services.set(IUpdateService, new SyncDescriptor(UpdateManager));
475494
services.set(IURLService, new SyncDescriptor(URLService, args['open-url']));
476495

477-
const instantiationService = new InstantiationService(services);
496+
return new InstantiationService(services);
497+
}
498+
499+
function start(): void {
500+
let args: ParsedArgs;
501+
502+
try {
503+
args = parseMainProcessArgv(process.argv);
504+
args = validatePaths(args);
505+
} catch (err) {
506+
console.error(err.message);
507+
process.exit(1);
508+
return;
509+
}
510+
511+
const instantiationService = createServices(args);
478512

479513
// On some platforms we need to manually read from the global environment variables
480514
// and assign them to the process environment (e.g. when doubleclick app on Mac)

src/vs/code/electron-main/menus.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { IPath, VSCodeWindow } from 'vs/code/electron-main/window';
1515
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1616
import { IStorageService } from 'vs/code/electron-main/storage';
1717
import { IFilesConfiguration, AutoSaveConfiguration } from 'vs/platform/files/common/files';
18-
import { IUpdateService, State as UpdateState } from 'vs/code/electron-main/update-manager';
18+
import { IUpdateService, State as UpdateState } from 'vs/platform/update/common/update';
1919
import { Keybinding } from 'vs/base/common/keybinding';
2020
import product from 'vs/platform/product';
2121

@@ -125,7 +125,7 @@ export class VSCodeMenu {
125125
this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config, true /* update menu if changed */));
126126

127127
// Listen to update service
128-
this.updateService.on('change', () => this.updateMenu());
128+
this.updateService.onStateChange(() => this.updateMenu());
129129
}
130130

131131
private onConfigurationUpdated(config: IConfiguration, handleMenu?: boolean): void {
@@ -751,11 +751,10 @@ export class VSCodeMenu {
751751
return [];
752752

753753
case UpdateState.UpdateDownloaded:
754-
const update = this.updateService.availableUpdate;
755754
return [new MenuItem({
756755
label: nls.localize('miRestartToUpdate', "Restart To Update..."), click: () => {
757756
this.reportMenuActionTelemetry('RestartToUpdate');
758-
update.quitAndUpdate();
757+
this.updateService.quitAndInstall();
759758
}
760759
})];
761760

@@ -764,10 +763,9 @@ export class VSCodeMenu {
764763

765764
case UpdateState.UpdateAvailable:
766765
if (platform.isLinux) {
767-
const update = this.updateService.availableUpdate;
768766
return [new MenuItem({
769767
label: nls.localize('miDownloadUpdate', "Download Available Update"), click: () => {
770-
update.quitAndUpdate();
768+
this.updateService.quitAndInstall();
771769
}
772770
})];
773771
}
@@ -782,7 +780,7 @@ export class VSCodeMenu {
782780
const result = [new MenuItem({
783781
label: nls.localize('miCheckForUpdates', "Check For Updates..."), click: () => setTimeout(() => {
784782
this.reportMenuActionTelemetry('CheckForUpdate');
785-
this.updateService.checkForUpdates(true);
783+
this.updateService.checkForUpdates(true).done(null, err => console.error(err));
786784
}, 0)
787785
})];
788786

0 commit comments

Comments
 (0)