提交 e96de2e6 编写于 作者: J Joao Moreno

ipc: add proper events to update service

上级 2ce7cc64
......@@ -77,7 +77,6 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
const environmentService = accessor.get(IEnvironmentService);
const windowsMainService = accessor.get(IWindowsMainService);
const lifecycleService = accessor.get(ILifecycleService);
const updateService = accessor.get(IUpdateService);
const configurationService = accessor.get(IConfigurationService) as ConfigurationService<any>;
const windowEventChannel = new WindowEventChannel(windowsMainService);
......@@ -255,9 +254,6 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
}
}
// Setup auto update
updateService.initialize();
// Open our first window
if (environmentService.args['new-window'] && environmentService.args._.length === 0) {
windowsMainService.open({ cli: environmentService.args, forceNewWindow: true, forceEmpty: true }); // new window if "-n" was used without paths
......
......@@ -125,7 +125,7 @@ export class VSCodeMenu {
this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config, true /* update menu if changed */));
// Listen to update service
this.updateService.on('change', () => this.updateMenu());
this.updateService.onStateChange(() => this.updateMenu());
}
private onConfigurationUpdated(config: IConfiguration, handleMenu?: boolean): void {
......
......@@ -8,7 +8,7 @@
import * as fs from 'original-fs';
import * as path from 'path';
import * as electron from 'electron';
import { EventEmitter } from 'events';
import Event, { Emitter } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Win32AutoUpdaterImpl } from 'vs/code/electron-main/auto-updater.win32';
import { LinuxAutoUpdaterImpl } from 'vs/code/electron-main/auto-updater.linux';
......@@ -37,7 +37,7 @@ export interface IUpdate {
quitAndUpdate: () => void;
}
interface IAutoUpdater extends NodeJS.EventEmitter {
interface IRawAutoUpdater extends NodeJS.EventEmitter {
setFeedURL(url: string): void;
checkForUpdates(): void;
}
......@@ -46,40 +46,57 @@ export const IUpdateService = createDecorator<IUpdateService>('updateService');
export interface IUpdateService {
_serviceBrand: any;
feedUrl: string;
channel: string;
initialize(): void;
state: State;
availableUpdate: IUpdate;
lastCheckDate: Date;
readonly onError: Event<any>;
readonly onCheckForUpdate: Event<void>;
readonly onUpdateAvailable: Event<{ url: string; version: string; }>;
readonly onUpdateNotAvailable: Event<boolean>;
readonly onUpdateReady: Event<IUpdate>;
readonly onStateChange: Event<void>;
readonly state: State;
readonly availableUpdate: IUpdate;
checkForUpdates(explicit: boolean): void;
on(event: string, listener: Function): this;
}
export class UpdateManager extends EventEmitter implements IUpdateService {
export class UpdateManager implements IUpdateService {
_serviceBrand: any;
private _state: State;
private explicitState: ExplicitState;
private _availableUpdate: IUpdate;
private _lastCheckDate: Date;
private raw: IAutoUpdater;
private raw: IRawAutoUpdater;
private _feedUrl: string;
private _channel: string;
private _onError = new Emitter<any>();
get onError(): Event<any> { return this._onError.event; }
private _onCheckForUpdate = new Emitter<void>();
get onCheckForUpdate(): Event<void> { return this._onCheckForUpdate.event; }
private _onUpdateAvailable = new Emitter<{ url: string; version: string; }>();
get onUpdateAvailable(): Event<{ url: string; version: string; }> { return this._onUpdateAvailable.event; }
private _onUpdateNotAvailable = new Emitter<boolean>();
get onUpdateNotAvailable(): Event<boolean> { return this._onUpdateNotAvailable.event; }
private _onUpdateReady = new Emitter<IUpdate>();
get onUpdateReady(): Event<IUpdate> { return this._onUpdateReady.event; }
private _onStateChange = new Emitter<void>();
get onStateChange(): Event<void> { return this._onStateChange.event; }
constructor(
@IInstantiationService instantiationService: IInstantiationService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IConfigurationService private configurationService: IConfigurationService,
@IRequestService requestService: IRequestService
) {
super();
this._state = State.Uninitialized;
this.explicitState = ExplicitState.Implicit;
this._availableUpdate = null;
this._lastCheckDate = null;
this._feedUrl = null;
this._channel = null;
......@@ -91,24 +108,23 @@ export class UpdateManager extends EventEmitter implements IUpdateService {
this.raw = electron.autoUpdater;
}
if (this.raw) {
this.initRaw();
if (!this.raw) {
return;
}
}
private initRaw(): void {
this.raw.on('error', (event: any, message: string) => {
this.emit('error', event, message);
// TODO: improve
console.error(message);
this.setState(State.Idle);
});
this.raw.on('checking-for-update', () => {
this.emit('checking-for-update');
this._onCheckForUpdate.fire();
this.setState(State.CheckingForUpdate);
});
this.raw.on('update-available', (event, url: string, version: string) => {
this.emit('update-available', url, version);
this._onUpdateAvailable.fire({ url, version });
let data: IUpdate = null;
......@@ -125,7 +141,7 @@ export class UpdateManager extends EventEmitter implements IUpdateService {
});
this.raw.on('update-not-available', () => {
this.emit('update-not-available', this.explicitState === ExplicitState.Explicit);
this._onUpdateNotAvailable.fire(this.explicitState === ExplicitState.Explicit);
this.setState(State.Idle);
});
......@@ -137,40 +153,9 @@ export class UpdateManager extends EventEmitter implements IUpdateService {
quitAndUpdate: () => this.quitAndUpdate(rawQuitAndUpdate)
};
this.emit('update-downloaded', data);
this._onUpdateReady.fire(data);
this.setState(State.UpdateDownloaded, data);
});
}
private quitAndUpdate(rawQuitAndUpdate: () => void): void {
this.lifecycleService.quit(true /* from update */).done(vetod => {
if (vetod) {
return;
}
// for some reason updating on Mac causes the local storage not to be flushed.
// we workaround this issue by forcing an explicit flush of the storage data.
// see also https://github.com/Microsoft/vscode/issues/172
if (process.platform === 'darwin') {
electron.session.defaultSession.flushStorageData();
}
rawQuitAndUpdate();
});
}
public get feedUrl(): string {
return this._feedUrl;
}
public get channel(): string {
return this._channel;
}
public initialize(): void {
if (this.feedUrl) {
return; // already initialized
}
const channel = this.getUpdateChannel();
const feedUrl = this.getUpdateFeedUrl(channel);
......@@ -194,39 +179,46 @@ export class UpdateManager extends EventEmitter implements IUpdateService {
let timer = setTimeout(() => this.checkForUpdates(), 30 * 1000);
// Clear timer when checking for update
this.on('error', (error: any, message: string) => console.error(error, message));
// Clear timer when checking for update
this.on('checking-for-update', () => clearTimeout(timer));
this.onCheckForUpdate(() => clearTimeout(timer));
// If update not found, try again in 1 hour
this.on('update-not-available', () => {
timer = setTimeout(() => this.checkForUpdates(), 60 * 60 * 1000);
this.onUpdateNotAvailable(() => timer = setTimeout(() => this.checkForUpdates(), 60 * 60 * 1000));
}
private quitAndUpdate(rawQuitAndUpdate: () => void): void {
this.lifecycleService.quit(true /* from update */).done(vetod => {
if (vetod) {
return;
}
// for some reason updating on Mac causes the local storage not to be flushed.
// we workaround this issue by forcing an explicit flush of the storage data.
// see also https://github.com/Microsoft/vscode/issues/172
if (process.platform === 'darwin') {
electron.session.defaultSession.flushStorageData();
}
rawQuitAndUpdate();
});
}
public get state(): State {
get state(): State {
return this._state;
}
public get availableUpdate(): IUpdate {
get availableUpdate(): IUpdate {
return this._availableUpdate;
}
public get lastCheckDate(): Date {
return this._lastCheckDate;
}
public checkForUpdates(explicit = false): void {
checkForUpdates(explicit = false): void {
this.explicitState = explicit ? ExplicitState.Explicit : ExplicitState.Implicit;
this._lastCheckDate = new Date();
this.raw.checkForUpdates();
}
private setState(state: State, availableUpdate: IUpdate = null): void {
this._state = state;
this._availableUpdate = availableUpdate;
this.emit('change');
this._onStateChange.fire();
}
private getUpdateChannel(): string {
......
......@@ -22,7 +22,7 @@ import { ipcMain as ipc, app, screen, BrowserWindow, dialog } from 'electron';
import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/electron-main/paths';
import { ILifecycleService } from 'vs/code/electron-main/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IUpdateService, IUpdate } from 'vs/code/electron-main/update-manager';
import { IUpdateService } from 'vs/code/electron-main/update-manager';
import { ILogService } from 'vs/code/electron-main/log';
import { IWindowEventService } from 'vs/code/common/windows';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -249,7 +249,7 @@ export class WindowsManager implements IWindowsMainService, IWindowEventService
}
});
this.updateService.on('update-downloaded', (update: IUpdate) => {
this.updateService.onUpdateReady(update => {
this.sendToFocused('vscode:telemetry', { eventName: 'update:downloaded', data: { version: update.version } });
this.sendToAll('vscode:update-downloaded', JSON.stringify({
......@@ -267,7 +267,7 @@ export class WindowsManager implements IWindowsMainService, IWindowEventService
}
});
this.updateService.on('update-not-available', (explicit: boolean) => {
this.updateService.onUpdateNotAvailable(explicit => {
this.sendToFocused('vscode:telemetry', { eventName: 'update:notAvailable', data: { explicit } });
if (explicit) {
......@@ -275,7 +275,7 @@ export class WindowsManager implements IWindowsMainService, IWindowEventService
}
});
this.updateService.on('update-available', (url: string, version: string) => {
this.updateService.onUpdateAvailable(({ url, version }) => {
if (url) {
this.sendToFocused('vscode:update-available', url, version);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册