diff --git a/src/vs/base/browser/idleMonitor.ts b/src/vs/base/browser/idleMonitor.ts index 993523069945af86dd589b6e584332b47849b760..b1f990786df81663a7104d5cc5957703b1b428e4 100644 --- a/src/vs/base/browser/idleMonitor.ts +++ b/src/vs/base/browser/idleMonitor.ts @@ -4,29 +4,14 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import { UserStatus, IIdleMonitor } from 'vs/base/common/idleMonitor'; import {TimeoutTimer} from 'vs/base/common/async'; import Event, {Emitter} from 'vs/base/common/event'; -import {Disposable, IDisposable} from 'vs/base/common/lifecycle'; +import {Disposable} from 'vs/base/common/lifecycle'; import * as dom from 'vs/base/browser/dom'; -export enum UserStatus { - Idle, - Active -} - -export interface IIdleMonitor extends IDisposable { - status: UserStatus; - onStatusChange: Event; -} - export const DEFAULT_IDLE_TIME = 60 * 60 * 1000; // 60 minutes -export class NeverIdleMonitor implements IIdleMonitor { - status = UserStatus.Active; - onStatusChange = new Emitter().event; - dispose() {} -} - export class IdleMonitor extends Disposable implements IIdleMonitor { private _lastActiveTime: number; diff --git a/src/vs/base/common/idleMonitor.ts b/src/vs/base/common/idleMonitor.ts new file mode 100644 index 0000000000000000000000000000000000000000..1dde52d0edb599ab5ab5943d5a8ccc4f2d253726 --- /dev/null +++ b/src/vs/base/common/idleMonitor.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import Event, { Emitter } from 'vs/base/common/event'; +import { IDisposable } from 'vs/base/common/lifecycle'; + +export enum UserStatus { + Idle, + Active +} + +export interface IIdleMonitor extends IDisposable { + status: UserStatus; + onStatusChange: Event; +} + +export class NeverIdleMonitor implements IIdleMonitor { + status = UserStatus.Active; + onStatusChange = new Emitter().event; + dispose() {} +} \ No newline at end of file diff --git a/src/vs/platform/telemetry/browser/telemetryService.ts b/src/vs/platform/telemetry/browser/telemetryService.ts index c926d353187e4c5e1bca5b14c2a095bab3d4edf4..d8ef2417b8134801343e562355947f91c70bf7a1 100644 --- a/src/vs/platform/telemetry/browser/telemetryService.ts +++ b/src/vs/platform/telemetry/browser/telemetryService.ts @@ -11,7 +11,7 @@ import {ITelemetryService, ITelemetryAppender, ITelemetryInfo} from 'vs/platform import {optional} from 'vs/platform/instantiation/common/instantiation'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IConfigurationRegistry, Extensions} from 'vs/platform/configuration/common/configurationRegistry'; -import {IIdleMonitor, IdleMonitor, UserStatus} from 'vs/base/browser/idleMonitor'; +import {IIdleMonitor, UserStatus} from 'vs/base/common/idleMonitor'; import {TPromise} from 'vs/base/common/winjs.base'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TimeKeeper, ITimerEvent} from 'vs/base/common/timer'; @@ -20,8 +20,8 @@ import {Registry} from 'vs/platform/platform'; export interface ITelemetryServiceConfig { appender: ITelemetryAppender[]; - hardIdleMonitor?: IIdleMonitor; - softIdleMonitor?: IIdleMonitor; + hardIdleMonitor: IIdleMonitor; + softIdleMonitor: IIdleMonitor; commonProperties?: TPromise<{ [name: string]: any }>; piiPaths?: string[]; userOptIn?: boolean; @@ -49,6 +49,8 @@ export class TelemetryService implements ITelemetryService { ) { this._configuration = mixin(config, { appender: [], + hardIdleMonitor: null, + softIdleMonitor: null, commonProperties: TPromise.as({}), piiPaths: [], userOptIn: true @@ -71,14 +73,12 @@ export class TelemetryService implements ITelemetryService { this._disposables.push(this._timeKeeper); this._disposables.push(this._timeKeeper.addListener(events => this._onTelemetryTimerEventStop(events))); - this._hardIdleMonitor = this._configuration.hardIdleMonitor || new IdleMonitor(); - // TODO@joao remove - this._disposables.push(this._hardIdleMonitor); + this._hardIdleMonitor = this._configuration.hardIdleMonitor; + this._softIdleMonitor = this._configuration.softIdleMonitor; - this._softIdleMonitor = this._configuration.softIdleMonitor || new IdleMonitor(TelemetryService.SOFT_IDLE_TIME); - this._disposables.push(this._softIdleMonitor.onStatusChange(status => this._onIdleStatus(status))); - // TODO@joao remove - this._disposables.push(this._softIdleMonitor); + if (this._softIdleMonitor) { + this._disposables.push(this._softIdleMonitor.onStatusChange(status => this._onIdleStatus(status))); + } if (this._configurationService) { this._updateUserOptIn(); diff --git a/src/vs/platform/telemetry/test/node/telemetryService.test.ts b/src/vs/platform/telemetry/test/node/telemetryService.test.ts index 89c9ff64346ea5d41259d0cb355136f1af6330f5..76bf5eb3449121aa794a761c8f93de44e1e07177 100644 --- a/src/vs/platform/telemetry/test/node/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/node/telemetryService.test.ts @@ -5,7 +5,8 @@ 'use strict'; import * as assert from 'assert'; -import IdleMonitor = require('vs/base/browser/idleMonitor'); +import {NeverIdleMonitor, UserStatus} from 'vs/base/common/idleMonitor'; +import * as IdleMonitor from 'vs/base/browser/idleMonitor'; import {Emitter} from 'vs/base/common/event'; import {TPromise} from 'vs/base/common/winjs.base'; import {TelemetryService} from 'vs/platform/telemetry/browser/telemetryService'; @@ -86,12 +87,16 @@ suite('TelemetryService', () => { test('Disposing', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testPrivateEvent').then(() => { assert.equal(testAppender.getEventsCount(), 1); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); assert.equal(!testAppender.isDisposed, true); }); })); @@ -99,7 +104,9 @@ suite('TelemetryService', () => { // event reporting test('Simple event', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent').then(_ => { assert.equal(testAppender.getEventsCount(), 1); @@ -107,12 +114,16 @@ suite('TelemetryService', () => { assert.notEqual(testAppender.events[0].data, null); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); })); test('Event with data', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent', { 'stringProp': 'property', @@ -131,14 +142,18 @@ suite('TelemetryService', () => { assert.equal(testAppender.events[0].data['complexProp'].value, 0); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); })); test('common properties added to *all* events, simple event', function () { let testAppender = new TestTelemetryAppender(); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); let service = new TelemetryService({ - appender: [testAppender], + appender: [testAppender], hardIdleMonitor, softIdleMonitor, commonProperties: TPromise.as({ foo: 'JA!', get bar() { return Math.random(); } }) }, undefined); @@ -150,13 +165,17 @@ suite('TelemetryService', () => { assert.equal(typeof first.data['bar'], 'number'); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); }); test('common properties added to *all* events, event with data', function () { let testAppender = new TestTelemetryAppender(); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); let service = new TelemetryService({ - appender: [testAppender], + appender: [testAppender], hardIdleMonitor, softIdleMonitor, commonProperties: TPromise.as({ foo: 'JA!', get bar() { return Math.random(); } }) }, undefined); @@ -170,12 +189,16 @@ suite('TelemetryService', () => { assert.equal(typeof first.data['price'], 'number'); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); }); test('TelemetryInfo comes from properties', function () { + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); let service = new TelemetryService({ - appender: [], + appender: [], hardIdleMonitor, softIdleMonitor, commonProperties: TPromise.as({ sessionID: 'one', ['common.instanceId']: 'two', @@ -187,6 +210,10 @@ suite('TelemetryService', () => { assert.equal(info.sessionId, 'one'); assert.equal(info.instanceId, 'two'); assert.equal(info.machineId, 'three'); + + service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); }); @@ -194,7 +221,9 @@ suite('TelemetryService', () => { Timer.ENABLE_TIMER = true; let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); let t1 = service.timedPublicLog('editorDance'); this.clock.tick(20); @@ -221,18 +250,24 @@ suite('TelemetryService', () => { assert.equal(testAppender.events[2].data.someData, 'data'); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); Timer.ENABLE_TIMER = false; })); test('enableTelemetry on by default', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent').then(() => { assert.equal(testAppender.getEventsCount(), 1); assert.equal(testAppender.events[0].eventName, 'testEvent'); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); })); @@ -243,7 +278,9 @@ suite('TelemetryService', () => { try { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); @@ -261,6 +298,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); } @@ -299,7 +338,9 @@ suite('TelemetryService', () => { let errorStub = this.stub(window, 'onerror'); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let testError = new Error('test'); @@ -319,13 +360,17 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); })); test('Uncaught Error Telemetry removes PII from filename', sinon.test(function () { let errorStub = this.stub(window, 'onerror'); let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let dangerousFilenameError: any = new Error('dangerousFilename'); @@ -347,6 +392,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); })); test('Unexpected Error Telemetry removes PII', sinon.test(function () { @@ -355,7 +402,9 @@ suite('TelemetryService', () => { try { let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let dangerousPathWithoutImportantInfoError: any = new Error(settings.dangerousPathWithoutImportantInfo); @@ -373,6 +422,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); @@ -383,7 +434,9 @@ suite('TelemetryService', () => { let errorStub = this.stub(window, 'onerror'); let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let dangerousPathWithoutImportantInfoError: any = new Error('dangerousPathWithoutImportantInfo'); @@ -402,6 +455,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); })); test('Unexpected Error Telemetry removes PII but preserves Code file path', sinon.test(function () { @@ -412,7 +467,9 @@ suite('TelemetryService', () => { try { let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo); @@ -433,6 +490,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); @@ -443,7 +502,9 @@ suite('TelemetryService', () => { let errorStub = this.stub(window, 'onerror'); let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); @@ -464,6 +525,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); })); test('Unexpected Error Telemetry removes PII but preserves Missing Model error message', sinon.test(function () { @@ -474,7 +537,9 @@ suite('TelemetryService', () => { try { let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let missingModelError: any = new Error(settings.missingModelMessage); @@ -496,6 +561,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); } @@ -505,7 +572,9 @@ suite('TelemetryService', () => { let errorStub = this.stub(window, 'onerror'); let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let missingModelError: any = new Error('missingModelMessage'); @@ -527,6 +596,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); })); test('Unexpected Error Telemetry removes PII but preserves No Such File error message', sinon.test(function () { @@ -537,7 +608,9 @@ suite('TelemetryService', () => { try { let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let noSuchFileError: any = new Error(settings.noSuchFileMessage); @@ -559,6 +632,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); } @@ -572,7 +647,9 @@ suite('TelemetryService', () => { let errorStub = this.stub(window, 'onerror'); let settings = new ErrorTestingSettings(); let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); const errorTelemetry = new ErrorTelemetry(service); let noSuchFileError: any = new Error('noSuchFileMessage'); @@ -595,6 +672,8 @@ suite('TelemetryService', () => { errorTelemetry.dispose(); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); } finally { Errors.setUnexpectedErrorHandler(origErrorHandler); } @@ -603,7 +682,9 @@ suite('TelemetryService', () => { test('Test hard idle does not affect sending normal events in active state', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ softIdleMonitor: new IdleMonitor.NeverIdleMonitor(), appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new NeverIdleMonitor(); + let service = new TelemetryService({ hardIdleMonitor, softIdleMonitor, appender: [testAppender] }, undefined); //report an event @@ -613,13 +694,15 @@ suite('TelemetryService', () => { assert.equal(testAppender.getEventsCount(), 1); service.dispose(); + softIdleMonitor.dispose(); })); - test('Test hard idle stops events from being sent in idle state', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ softIdleMonitor: new IdleMonitor.NeverIdleMonitor(), appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new NeverIdleMonitor(); + let service = new TelemetryService({ hardIdleMonitor, softIdleMonitor, appender: [testAppender] }, undefined); // make the user idle this.clock.tick(IdleMonitor.DEFAULT_IDLE_TIME); @@ -630,8 +713,8 @@ suite('TelemetryService', () => { assert.equal(testAppender.getEventsCount(), 0); service.dispose(); + softIdleMonitor.dispose(); }); - })); test('Test soft idle start/stop events', sinon.test(function () { @@ -644,18 +727,18 @@ suite('TelemetryService', () => { } MockIdleMonitor.prototype.onStatusChange = (callback) => { - activeListener = () => callback(IdleMonitor.UserStatus.Active); - idleListener = () => callback(IdleMonitor.UserStatus.Idle); + activeListener = () => callback(UserStatus.Active); + idleListener = () => callback(UserStatus.Idle); }; MockIdleMonitor.prototype.dispose = function () { // empty }; - this.stub(IdleMonitor, 'IdleMonitor', MockIdleMonitor); - let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ hardIdleMonitor: new IdleMonitor.NeverIdleMonitor(), appender: [testAppender] }, undefined); + const hardIdleMonitor = new NeverIdleMonitor(); + const softIdleMonitor = new MockIdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ hardIdleMonitor, softIdleMonitor, appender: [testAppender] }, undefined); assert.equal(testAppender.getEventsCount(), 0); @@ -675,11 +758,14 @@ suite('TelemetryService', () => { assert.equal(testAppender.events[3].eventName, TelemetryService.IDLE_STOP_EVENT_NAME); service.dispose(); + hardIdleMonitor.dispose(); })); test('Telemetry Service respects user opt-in settings', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: false, appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ userOptIn: false, appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent').then(() => { assert.equal(testAppender.getEventsCount(), 0); @@ -689,17 +775,23 @@ suite('TelemetryService', () => { test('Telemetry Service sends events when enableTelemetry is on even user optin is on', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: true, appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ userOptIn: true, appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent').then(() => { assert.equal(testAppender.getEventsCount(), 1); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); })); test('Telemetry Service allows optin friendly events', sinon.test(function () { let testAppender = new TestTelemetryAppender(); - let service = new TelemetryService({ userOptIn: false, appender: [testAppender] }, undefined); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + let service = new TelemetryService({ userOptIn: false, appender: [testAppender], hardIdleMonitor, softIdleMonitor }, undefined); return service.publicLog('testEvent').then(() => { assert.equal(testAppender.getEventsCount(), 0); @@ -709,6 +801,8 @@ suite('TelemetryService', () => { assert.equal(testAppender.events[0].eventName, optInStatusEventName); assert.equal(testAppender.events[0].data.userOptIn, false); service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); })); @@ -718,8 +812,10 @@ suite('TelemetryService', () => { let emitter = new Emitter(); let testAppender = new TestTelemetryAppender(); + const hardIdleMonitor = new IdleMonitor.IdleMonitor(); + const softIdleMonitor = new IdleMonitor.IdleMonitor(TelemetryService.SOFT_IDLE_TIME); let service = new TelemetryService({ - appender: [testAppender] + appender: [testAppender], hardIdleMonitor, softIdleMonitor }, { serviceId: undefined, hasWorkspaceConfiguration() { @@ -748,5 +844,9 @@ suite('TelemetryService', () => { enableTelemetry = false; emitter.fire({}); assert.equal(service.isOptedIn, false); + + service.dispose(); + hardIdleMonitor.dispose(); + softIdleMonitor.dispose(); }); }); \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index d7c7f060d261d229ab259a7cc159647e47f304ba..6fa841c88a04f14481e0538443154ede9d8033d7 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -20,7 +20,8 @@ import timer = require('vs/base/common/timer'); import {Workbench} from 'vs/workbench/browser/workbench'; import {Storage, inMemoryLocalStorageInstance} from 'vs/workbench/common/storage'; import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry'; -import {TelemetryService} from 'vs/platform/telemetry/browser/telemetryService'; +import {TelemetryService, ITelemetryServiceConfig} from 'vs/platform/telemetry/browser/telemetryService'; +import {IdleMonitor} from 'vs/base/browser/idleMonitor'; import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; import {createAppender} from 'vs/platform/telemetry/node/appInsightsAppender'; import {resolveCommonProperties} from 'vs/platform/telemetry/node/commonProperties'; @@ -214,15 +215,23 @@ export class WorkbenchShell { // Telemetry if (this.configuration.env.isBuilt && !this.configuration.env.extensionDevelopmentPath && !!this.configuration.env.enableTelemetry) { - const config = { - appender: createAppender(this.configuration.env), + const appender = createAppender(this.configuration.env); + const hardIdleMonitor = new IdleMonitor(); + const softIdleMonitor = new IdleMonitor(TelemetryService.SOFT_IDLE_TIME); + + const config: ITelemetryServiceConfig = { + appender, + hardIdleMonitor, + softIdleMonitor, commonProperties: resolveCommonProperties(this.storageService, this.contextService), piiPaths: [this.configuration.env.appRoot, this.configuration.env.userExtensionsHome] }; + const telemetryService = instantiationService.createInstance(TelemetryService, config); const errorTelemetry = new ErrorTelemetry(telemetryService); + this.telemetryService = telemetryService; - disposables.add(telemetryService, errorTelemetry, ...config.appender); + disposables.add(telemetryService, errorTelemetry, hardIdleMonitor, softIdleMonitor, ...appender); } else { this.telemetryService = NullTelemetryService; }