mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-03 09:35:40 -05:00
Merge from vscode aba87f135229c17c4624341b7a2499dcedafcb87 (#6430)
* Merge from vscode aba87f135229c17c4624341b7a2499dcedafcb87 * fix compile errors
This commit is contained in:
53
src/vs/platform/debug/common/extensionHostDebug.ts
Normal file
53
src/vs/platform/debug/common/extensionHostDebug.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IRemoteConsoleLog } from 'vs/base/common/console';
|
||||
|
||||
export const IExtensionHostDebugService = createDecorator<IExtensionHostDebugService>('extensionHostDebugService');
|
||||
|
||||
export interface IAttachSessionEvent {
|
||||
sessionId: string;
|
||||
subId?: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface ILogToSessionEvent {
|
||||
sessionId: string;
|
||||
log: IRemoteConsoleLog;
|
||||
}
|
||||
|
||||
export interface ITerminateSessionEvent {
|
||||
sessionId: string;
|
||||
subId?: string;
|
||||
}
|
||||
|
||||
export interface IReloadSessionEvent {
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export interface ICloseSessionEvent {
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export interface IExtensionHostDebugService {
|
||||
_serviceBrand: any;
|
||||
|
||||
reload(sessionId: string): void;
|
||||
onReload: Event<IReloadSessionEvent>;
|
||||
|
||||
close(sessionId: string): void;
|
||||
onClose: Event<ICloseSessionEvent>;
|
||||
|
||||
attachSession(sessionId: string, port: number, subId?: string): void;
|
||||
onAttachSession: Event<IAttachSessionEvent>;
|
||||
|
||||
logToSession(sessionId: string, log: IRemoteConsoleLog): void;
|
||||
onLogToSession: Event<ILogToSessionEvent>;
|
||||
|
||||
terminateSession(sessionId: string, subId?: string): void;
|
||||
onTerminateSession: Event<ITerminateSessionEvent>;
|
||||
}
|
||||
99
src/vs/platform/debug/common/extensionHostDebugIpc.ts
Normal file
99
src/vs/platform/debug/common/extensionHostDebugIpc.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IReloadSessionEvent, ICloseSessionEvent, IAttachSessionEvent, ILogToSessionEvent, ITerminateSessionEvent, IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IRemoteConsoleLog } from 'vs/base/common/console';
|
||||
|
||||
export class ExtensionHostDebugBroadcastChannel<TContext> implements IServerChannel<TContext> {
|
||||
|
||||
static readonly ChannelName = 'extensionhostdebugservice';
|
||||
|
||||
private _onCloseEmitter = new Emitter<ICloseSessionEvent>();
|
||||
private _onReloadEmitter = new Emitter<IReloadSessionEvent>();
|
||||
private _onTerminateEmitter = new Emitter<ITerminateSessionEvent>();
|
||||
private _onLogToEmitter = new Emitter<ILogToSessionEvent>();
|
||||
private _onAttachEmitter = new Emitter<IAttachSessionEvent>();
|
||||
|
||||
call(ctx: TContext, command: string, arg?: any): Promise<any> {
|
||||
switch (command) {
|
||||
case 'close':
|
||||
return Promise.resolve(this._onCloseEmitter.fire({ sessionId: arg[0] }));
|
||||
case 'reload':
|
||||
return Promise.resolve(this._onReloadEmitter.fire({ sessionId: arg[0] }));
|
||||
case 'terminate':
|
||||
return Promise.resolve(this._onTerminateEmitter.fire({ sessionId: arg[0] }));
|
||||
case 'log':
|
||||
return Promise.resolve(this._onLogToEmitter.fire({ sessionId: arg[0], log: arg[1] }));
|
||||
case 'attach':
|
||||
return Promise.resolve(this._onAttachEmitter.fire({ sessionId: arg[0], port: arg[1], subId: arg[2] }));
|
||||
}
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
listen(ctx: TContext, event: string, arg?: any): Event<any> {
|
||||
switch (event) {
|
||||
case 'close':
|
||||
return this._onCloseEmitter.event;
|
||||
case 'reload':
|
||||
return this._onReloadEmitter.event;
|
||||
case 'terminate':
|
||||
return this._onTerminateEmitter.event;
|
||||
case 'log':
|
||||
return this._onLogToEmitter.event;
|
||||
case 'attach':
|
||||
return this._onAttachEmitter.event;
|
||||
}
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionHostDebugChannelClient implements IExtensionHostDebugService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(private channel: IChannel) { }
|
||||
|
||||
reload(sessionId: string): void {
|
||||
this.channel.call('reload', [sessionId]);
|
||||
}
|
||||
|
||||
get onReload(): Event<IReloadSessionEvent> {
|
||||
return this.channel.listen('reload');
|
||||
}
|
||||
|
||||
close(sessionId: string): void {
|
||||
this.channel.call('close', [sessionId]);
|
||||
}
|
||||
|
||||
get onClose(): Event<ICloseSessionEvent> {
|
||||
return this.channel.listen('close');
|
||||
}
|
||||
|
||||
attachSession(sessionId: string, port: number, subId?: string): void {
|
||||
this.channel.call('attach', [sessionId, port, subId]);
|
||||
}
|
||||
|
||||
get onAttachSession(): Event<IAttachSessionEvent> {
|
||||
return this.channel.listen('attach');
|
||||
}
|
||||
|
||||
logToSession(sessionId: string, log: IRemoteConsoleLog): void {
|
||||
this.channel.call('log', [sessionId, log]);
|
||||
}
|
||||
|
||||
get onLogToSession(): Event<ILogToSessionEvent> {
|
||||
return this.channel.listen('log');
|
||||
}
|
||||
|
||||
terminateSession(sessionId: string, subId?: string): void {
|
||||
this.channel.call('terminate', [sessionId, subId]);
|
||||
}
|
||||
|
||||
get onTerminateSession(): Event<ITerminateSessionEvent> {
|
||||
return this.channel.listen('terminate');
|
||||
}
|
||||
}
|
||||
@@ -520,14 +520,17 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
if (folderUri.scheme === 'file') {
|
||||
const folder = folderUri.fsPath;
|
||||
collectWorkspaceStats(folder, ['node_modules', '.git']).then(stats => {
|
||||
/* __GDPR__
|
||||
"workspace.stats" : {
|
||||
"fileTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"configTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"launchConfigs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('workspace.stats', {
|
||||
type WorkspaceStatsClassification = {
|
||||
fileTypes: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
configTypes: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
launchConfigs: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
};
|
||||
type WorkspaceStatsEvent = {
|
||||
fileTypes: WorkspaceStatItem[];
|
||||
configTypes: WorkspaceStatItem[];
|
||||
launchConfigs: WorkspaceStatItem[];
|
||||
};
|
||||
this.telemetryService.publicLog2<WorkspaceStatsEvent, WorkspaceStatsClassification>('workspace.stats', {
|
||||
fileTypes: stats.fileTypes,
|
||||
configTypes: stats.configFiles,
|
||||
launchConfigs: stats.launchConfigFiles
|
||||
|
||||
@@ -140,7 +140,7 @@ export interface IEnvironmentService {
|
||||
isExtensionDevelopment: boolean;
|
||||
disableExtensions: boolean | string[];
|
||||
builtinExtensionsPath: string;
|
||||
extensionsPath: string;
|
||||
extensionsPath?: string;
|
||||
extensionDevelopmentLocationURI?: URI[];
|
||||
extensionTestsLocationURI?: URI;
|
||||
|
||||
@@ -178,4 +178,6 @@ export interface IEnvironmentService {
|
||||
webviewEndpoint?: string;
|
||||
readonly webviewResourceRoot: string;
|
||||
readonly webviewCspSource: string;
|
||||
|
||||
readonly galleryMachineIdResource?: URI;
|
||||
}
|
||||
|
||||
@@ -266,6 +266,9 @@ export class EnvironmentService implements IEnvironmentService {
|
||||
@memoize
|
||||
get nodeCachedDataDir(): string | undefined { return process.env['VSCODE_NODE_CACHED_DATA_DIR'] || undefined; }
|
||||
|
||||
@memoize
|
||||
get galleryMachineIdResource(): URI { return resources.joinPath(URI.file(this.userDataPath), 'machineid'); }
|
||||
|
||||
get disableUpdates(): boolean { return !!this._args['disable-updates']; }
|
||||
get disableCrashReporter(): boolean { return !!this._args['disable-crash-reporter']; }
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getGalleryExtensionId, getGalleryExtensionTelemetryData, adoptToGallery
|
||||
import { assign, getOrDefault } from 'vs/base/common/objects';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IPager } from 'vs/base/common/paging';
|
||||
import { IRequestService, IRequestOptions, IRequestContext, asJson, asText } from 'vs/platform/request/common/request';
|
||||
import { IRequestService, IRequestOptions, IRequestContext, asJson, asText, IHeaders } from 'vs/platform/request/common/request';
|
||||
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { generateUuid, isUUID } from 'vs/base/common/uuid';
|
||||
@@ -467,13 +467,15 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
let text = options.text || '';
|
||||
const pageSize = getOrDefault(options, o => o.pageSize, 50);
|
||||
|
||||
/* __GDPR__
|
||||
"galleryService:query" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"text": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('galleryService:query', { type, text });
|
||||
type GalleryServiceQueryClassification = {
|
||||
type: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
text: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
|
||||
};
|
||||
type GalleryServiceQueryEvent = {
|
||||
type: string;
|
||||
text: string;
|
||||
};
|
||||
this.telemetryService.publicLog2<GalleryServiceQueryEvent, GalleryServiceQueryClassification>('galleryService:query', { type, text });
|
||||
|
||||
let query = new Query()
|
||||
.withFlags(Flags.IncludeLatestVersionOnly, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
@@ -943,29 +945,30 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
||||
}
|
||||
|
||||
export async function resolveMarketplaceHeaders(version: string, environmentService: IEnvironmentService, fileService: IFileService): Promise<{ [key: string]: string; }> {
|
||||
const marketplaceMachineIdFile = joinPath(URI.file(environmentService.userDataPath), 'machineid');
|
||||
|
||||
let uuid: string | null = null;
|
||||
|
||||
try {
|
||||
const contents = await fileService.readFile(marketplaceMachineIdFile);
|
||||
const value = contents.value.toString();
|
||||
uuid = isUUID(value) ? value : null;
|
||||
} catch (e) {
|
||||
uuid = null;
|
||||
}
|
||||
|
||||
if (!uuid) {
|
||||
uuid = generateUuid();
|
||||
try {
|
||||
await fileService.writeFile(marketplaceMachineIdFile, VSBuffer.fromString(uuid));
|
||||
} catch (error) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
return {
|
||||
const headers: IHeaders = {
|
||||
'X-Market-Client-Id': `VSCode ${version}`,
|
||||
'User-Agent': `VSCode ${version}`,
|
||||
'X-Market-User-Id': uuid
|
||||
'User-Agent': `VSCode ${version}`
|
||||
};
|
||||
let uuid: string | null = null;
|
||||
if (environmentService.galleryMachineIdResource) {
|
||||
try {
|
||||
const contents = await fileService.readFile(environmentService.galleryMachineIdResource);
|
||||
const value = contents.value.toString();
|
||||
uuid = isUUID(value) ? value : null;
|
||||
} catch (e) {
|
||||
uuid = null;
|
||||
}
|
||||
|
||||
if (!uuid) {
|
||||
uuid = generateUuid();
|
||||
try {
|
||||
await fileService.writeFile(environmentService.galleryMachineIdResource, VSBuffer.fromString(uuid));
|
||||
} catch (error) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
headers['X-Market-User-Id'] = uuid;
|
||||
}
|
||||
return headers;
|
||||
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import { Event } from 'vs/base/common/event';
|
||||
import { IPager } from 'vs/base/common/paging';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IExtensionManifest, IExtension, ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
@@ -210,110 +209,6 @@ export interface IExtensionManagementService {
|
||||
updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension>;
|
||||
}
|
||||
|
||||
export const IExtensionManagementServerService = createDecorator<IExtensionManagementServerService>('extensionManagementServerService');
|
||||
|
||||
export interface IExtensionManagementServer {
|
||||
extensionManagementService: IExtensionManagementService;
|
||||
authority: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface IExtensionManagementServerService {
|
||||
_serviceBrand: any;
|
||||
readonly localExtensionManagementServer: IExtensionManagementServer;
|
||||
readonly remoteExtensionManagementServer: IExtensionManagementServer | null;
|
||||
getExtensionManagementServer(location: URI): IExtensionManagementServer | null;
|
||||
}
|
||||
|
||||
export const enum EnablementState {
|
||||
Disabled,
|
||||
WorkspaceDisabled,
|
||||
Enabled,
|
||||
WorkspaceEnabled
|
||||
}
|
||||
|
||||
export const IExtensionEnablementService = createDecorator<IExtensionEnablementService>('extensionEnablementService');
|
||||
|
||||
export interface IExtensionEnablementService {
|
||||
_serviceBrand: any;
|
||||
|
||||
readonly allUserExtensionsDisabled: boolean;
|
||||
|
||||
/**
|
||||
* Event to listen on for extension enablement changes
|
||||
*/
|
||||
onEnablementChanged: Event<IExtension[]>;
|
||||
|
||||
/**
|
||||
* Returns the enablement state for the given extension
|
||||
*/
|
||||
getEnablementState(extension: IExtension): EnablementState;
|
||||
|
||||
/**
|
||||
* Returns `true` if the enablement can be changed.
|
||||
*/
|
||||
canChangeEnablement(extension: IExtension): boolean;
|
||||
|
||||
/**
|
||||
* Returns `true` if the given extension identifier is enabled.
|
||||
*/
|
||||
isEnabled(extension: IExtension): boolean;
|
||||
|
||||
/**
|
||||
* Enable or disable the given extension.
|
||||
* if `workspace` is `true` then enablement is done for workspace, otherwise globally.
|
||||
*
|
||||
* Returns a promise that resolves to boolean value.
|
||||
* if resolves to `true` then requires restart for the change to take effect.
|
||||
*
|
||||
* Throws error if enablement is requested for workspace and there is no workspace
|
||||
*/
|
||||
setEnablement(extensions: IExtension[], state: EnablementState): Promise<boolean[]>;
|
||||
}
|
||||
|
||||
export interface IExtensionsConfigContent {
|
||||
recommendations: string[];
|
||||
unwantedRecommendations: string[];
|
||||
}
|
||||
|
||||
export type RecommendationChangeNotification = {
|
||||
extensionId: string,
|
||||
isRecommended: boolean
|
||||
};
|
||||
|
||||
export type DynamicRecommendation = 'dynamic';
|
||||
export type ExecutableRecommendation = 'executable';
|
||||
export type CachedRecommendation = 'cached';
|
||||
export type ApplicationRecommendation = 'application';
|
||||
export type ExtensionRecommendationSource = IWorkspace | IWorkspaceFolder | URI | DynamicRecommendation | ExecutableRecommendation | CachedRecommendation | ApplicationRecommendation;
|
||||
|
||||
export interface IExtensionRecommendation {
|
||||
extensionId: string;
|
||||
sources: ExtensionRecommendationSource[];
|
||||
}
|
||||
|
||||
export const IExtensionTipsService = createDecorator<IExtensionTipsService>('extensionTipsService');
|
||||
|
||||
export interface IExtensionTipsService {
|
||||
_serviceBrand: any;
|
||||
getAllRecommendationsWithReason(): { [id: string]: { reasonId: ExtensionRecommendationReason, reasonText: string }; };
|
||||
getFileBasedRecommendations(): IExtensionRecommendation[];
|
||||
getOtherRecommendations(): Promise<IExtensionRecommendation[]>;
|
||||
getWorkspaceRecommendations(): Promise<IExtensionRecommendation[]>;
|
||||
getKeymapRecommendations(): IExtensionRecommendation[];
|
||||
toggleIgnoredRecommendation(extensionId: string, shouldIgnore: boolean): void;
|
||||
getAllIgnoredRecommendations(): { global: string[], workspace: string[] };
|
||||
onRecommendationChange: Event<RecommendationChangeNotification>;
|
||||
}
|
||||
|
||||
export const enum ExtensionRecommendationReason {
|
||||
Workspace,
|
||||
File,
|
||||
Executable,
|
||||
DynamicWorkspace,
|
||||
Experimental
|
||||
}
|
||||
|
||||
export const ExtensionsLabel = localize('extensions', "Extensions");
|
||||
export const ExtensionsChannelId = 'extensions';
|
||||
export const PreferencesLabel = localize('preferences', "Preferences");
|
||||
|
||||
@@ -26,7 +26,7 @@ import { localizeManifest } from '../common/extensionNls';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { Limiter, createCancelablePromise, CancelablePromise, Queue } from 'vs/base/common/async';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as semver from 'semver';
|
||||
import * as semver from 'semver-umd';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import pkg from 'vs/platform/product/node/package';
|
||||
import { isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||
@@ -138,7 +138,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
) {
|
||||
super();
|
||||
this.systemExtensionsPath = environmentService.builtinExtensionsPath;
|
||||
this.extensionsPath = environmentService.extensionsPath;
|
||||
this.extensionsPath = environmentService.extensionsPath!;
|
||||
this.uninstalledPath = path.join(this.extensionsPath, '.obsolete');
|
||||
this.uninstalledFileLimiter = new Queue();
|
||||
this.manifestCache = this._register(new ExtensionsManifestCache(environmentService, this));
|
||||
|
||||
@@ -228,7 +228,8 @@ export class LaunchService implements ILaunchService {
|
||||
diffMode: args.diff,
|
||||
addMode: args.add,
|
||||
noRecentEntry: !!args['skip-add-to-recently-opened'],
|
||||
waitMarkerFileURI
|
||||
waitMarkerFileURI,
|
||||
gotoLineMode: args.goto
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -487,7 +487,8 @@ export class Menubar {
|
||||
context: OpenContext.MENU,
|
||||
cli: this.environmentService.args,
|
||||
urisToOpen: [uriToOpen],
|
||||
forceNewWindow: openInNewWindow
|
||||
forceNewWindow: openInNewWindow,
|
||||
gotoLineMode: false
|
||||
}).length > 0;
|
||||
|
||||
if (!success) {
|
||||
|
||||
@@ -21,7 +21,7 @@ export class ProductService implements IProductService {
|
||||
|
||||
get vscodeVersion(): string { return '1.35.0'; } // {{SQL CARBON EDIT}} add vscodeversion
|
||||
|
||||
get commit(): string | undefined { return undefined; }
|
||||
get commit(): string | undefined { return this.productConfiguration ? this.productConfiguration.commit : undefined; }
|
||||
|
||||
get nameLong(): string { return ''; }
|
||||
|
||||
@@ -46,4 +46,6 @@ export class ProductService implements IProductService {
|
||||
get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return this.productConfiguration ? this.productConfiguration.extensionKeywords : undefined; }
|
||||
|
||||
get extensionAllowedBadgeProviders(): readonly string[] | undefined { return this.productConfiguration ? this.productConfiguration.extensionAllowedBadgeProviders : undefined; }
|
||||
|
||||
get aiConfig() { return this.productConfiguration ? this.productConfiguration.aiConfig : undefined; }
|
||||
}
|
||||
@@ -38,6 +38,10 @@ export interface IProductService {
|
||||
readonly experimentsUrl?: string;
|
||||
readonly extensionKeywords?: { [extension: string]: readonly string[]; };
|
||||
readonly extensionAllowedBadgeProviders?: readonly string[];
|
||||
|
||||
readonly aiConfig?: {
|
||||
readonly asimovKey: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IProductConfiguration {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export const instanceStorageKey = 'telemetry.instanceId';
|
||||
export const currentSessionDateStorageKey = 'telemetry.currentSessionDate';
|
||||
export const firstSessionDateStorageKey = 'telemetry.firstSessionDate';
|
||||
export const lastSessionDateStorageKey = 'telemetry.lastSessionDate';
|
||||
|
||||
import * as Platform from 'vs/base/common/platform';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
|
||||
export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> {
|
||||
const result: { [name: string]: string | undefined; } = Object.create(null);
|
||||
const instanceId = storageService.get(instanceStorageKey, StorageScope.GLOBAL)!;
|
||||
const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!;
|
||||
const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!;
|
||||
|
||||
// __GDPR__COMMON__ "common.firstSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.firstSessionDate'] = firstSessionDate;
|
||||
// __GDPR__COMMON__ "common.lastSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.lastSessionDate'] = lastSessionDate || '';
|
||||
// __GDPR__COMMON__ "common.isNewSession" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.isNewSession'] = !lastSessionDate ? '1' : '0';
|
||||
// __GDPR__COMMON__ "common.instanceId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.instanceId'] = instanceId;
|
||||
// __GDPR__COMMON__ "common.remoteAuthority" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
|
||||
result['common.remoteAuthority'] = cleanRemoteAuthority(remoteAuthority);
|
||||
|
||||
// __GDPR__COMMON__ "common.machineId" : { "endPoint": "MacAddressHash", "classification": "EndUserPseudonymizedInformation", "purpose": "FeatureInsight" }
|
||||
result['common.machineId'] = machineId;
|
||||
// __GDPR__COMMON__ "sessionID" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['sessionID'] = uuid.generateUuid() + Date.now();
|
||||
// __GDPR__COMMON__ "commitHash" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
|
||||
result['commitHash'] = commit;
|
||||
// __GDPR__COMMON__ "version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['version'] = version;
|
||||
// __GDPR__COMMON__ "common.platform" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.platform'] = Platform.PlatformToString(Platform.platform);
|
||||
// __GDPR__COMMON__ "common.product" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
|
||||
result['common.product'] = 'web';
|
||||
// __GDPR__COMMON__ "common.userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
result['common.userAgent'] = Platform.userAgent;
|
||||
|
||||
// dynamic properties which value differs on each call
|
||||
let seq = 0;
|
||||
const startTime = Date.now();
|
||||
Object.defineProperties(result, {
|
||||
// __GDPR__COMMON__ "timestamp" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
'timestamp': {
|
||||
get: () => new Date(),
|
||||
enumerable: true
|
||||
},
|
||||
// __GDPR__COMMON__ "common.timesincesessionstart" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
'common.timesincesessionstart': {
|
||||
get: () => Date.now() - startTime,
|
||||
enumerable: true
|
||||
},
|
||||
// __GDPR__COMMON__ "common.sequence" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
'common.sequence': {
|
||||
get: () => seq++,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function cleanRemoteAuthority(remoteAuthority?: string): string {
|
||||
if (!remoteAuthority) {
|
||||
return 'none';
|
||||
}
|
||||
|
||||
let ret = 'other';
|
||||
// Whitelisted remote authorities
|
||||
['ssh-remote', 'dev-container', 'wsl'].forEach((res: string) => {
|
||||
if (remoteAuthority!.indexOf(`${res}+`) === 0) {
|
||||
ret = res;
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/com
|
||||
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
|
||||
import { safeStringify } from 'vs/base/common/objects';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
|
||||
export const NullTelemetryService = new class implements ITelemetryService {
|
||||
_serviceBrand: undefined;
|
||||
@@ -243,6 +245,77 @@ export function keybindingsTelemetry(telemetryService: ITelemetryService, keybin
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export interface Properties {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface Measurements {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
export function validateTelemetryData(data?: any): { properties: Properties, measurements: Measurements } {
|
||||
|
||||
const properties: Properties = Object.create(null);
|
||||
const measurements: Measurements = Object.create(null);
|
||||
|
||||
const flat = Object.create(null);
|
||||
flatten(data, flat);
|
||||
|
||||
for (let prop in flat) {
|
||||
// enforce property names less than 150 char, take the last 150 char
|
||||
prop = prop.length > 150 ? prop.substr(prop.length - 149) : prop;
|
||||
const value = flat[prop];
|
||||
|
||||
if (typeof value === 'number') {
|
||||
measurements[prop] = value;
|
||||
|
||||
} else if (typeof value === 'boolean') {
|
||||
measurements[prop] = value ? 1 : 0;
|
||||
|
||||
} else if (typeof value === 'string') {
|
||||
//enforce property value to be less than 1024 char, take the first 1024 char
|
||||
properties[prop] = value.substring(0, 1023);
|
||||
|
||||
} else if (typeof value !== 'undefined' && value !== null) {
|
||||
properties[prop] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
properties,
|
||||
measurements
|
||||
};
|
||||
}
|
||||
|
||||
function flatten(obj: any, result: { [key: string]: any }, order: number = 0, prefix?: string): void {
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let item of Object.getOwnPropertyNames(obj)) {
|
||||
const value = obj[item];
|
||||
const index = prefix ? prefix + item : item;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
result[index] = safeStringify(value);
|
||||
|
||||
} else if (value instanceof Date) {
|
||||
// TODO unsure why this is here and not in _getData
|
||||
result[index] = value.toISOString();
|
||||
|
||||
} else if (isObject(value)) {
|
||||
if (order < 2) {
|
||||
flatten(value, result, order + 1, index + '.');
|
||||
} else {
|
||||
result[index] = safeStringify(value);
|
||||
}
|
||||
} else {
|
||||
result[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function flattenKeys(value: Object | undefined): string[] {
|
||||
if (!value) {
|
||||
return [];
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as appInsights from 'applicationinsights';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
import { safeStringify, mixin } from 'vs/base/common/objects';
|
||||
import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
function getClient(aiKey: string): appInsights.TelemetryClient {
|
||||
@@ -35,13 +34,6 @@ function getClient(aiKey: string): appInsights.TelemetryClient {
|
||||
return client;
|
||||
}
|
||||
|
||||
interface Properties {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
interface Measurements {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
export class AppInsightsAppender implements ITelemetryAppender {
|
||||
|
||||
@@ -64,74 +56,12 @@ export class AppInsightsAppender implements ITelemetryAppender {
|
||||
}
|
||||
}
|
||||
|
||||
private static _getData(data?: any): { properties: Properties, measurements: Measurements } {
|
||||
|
||||
const properties: Properties = Object.create(null);
|
||||
const measurements: Measurements = Object.create(null);
|
||||
|
||||
const flat = Object.create(null);
|
||||
AppInsightsAppender._flaten(data, flat);
|
||||
|
||||
for (let prop in flat) {
|
||||
// enforce property names less than 150 char, take the last 150 char
|
||||
prop = prop.length > 150 ? prop.substr(prop.length - 149) : prop;
|
||||
const value = flat[prop];
|
||||
|
||||
if (typeof value === 'number') {
|
||||
measurements[prop] = value;
|
||||
|
||||
} else if (typeof value === 'boolean') {
|
||||
measurements[prop] = value ? 1 : 0;
|
||||
|
||||
} else if (typeof value === 'string') {
|
||||
//enforce property value to be less than 1024 char, take the first 1024 char
|
||||
properties[prop] = value.substring(0, 1023);
|
||||
|
||||
} else if (typeof value !== 'undefined' && value !== null) {
|
||||
properties[prop] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
properties,
|
||||
measurements
|
||||
};
|
||||
}
|
||||
|
||||
private static _flaten(obj: any, result: { [key: string]: any }, order: number = 0, prefix?: string): void {
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let item of Object.getOwnPropertyNames(obj)) {
|
||||
const value = obj[item];
|
||||
const index = prefix ? prefix + item : item;
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
result[index] = safeStringify(value);
|
||||
|
||||
} else if (value instanceof Date) {
|
||||
// TODO unsure why this is here and not in _getData
|
||||
result[index] = value.toISOString();
|
||||
|
||||
} else if (isObject(value)) {
|
||||
if (order < 2) {
|
||||
AppInsightsAppender._flaten(value, result, order + 1, index + '.');
|
||||
} else {
|
||||
result[index] = safeStringify(value);
|
||||
}
|
||||
} else {
|
||||
result[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log(eventName: string, data?: any): void {
|
||||
if (!this._aiClient) {
|
||||
return;
|
||||
}
|
||||
data = mixin(data, this._defaultData);
|
||||
data = AppInsightsAppender._getData(data);
|
||||
data = validateTelemetryData(data);
|
||||
|
||||
if (this._logService) {
|
||||
this._logService.trace(`telemetry/${eventName}`, data);
|
||||
|
||||
@@ -8,34 +8,36 @@ import { readdirSync } from 'vs/base/node/pfs';
|
||||
import { statSync, readFileSync } from 'fs';
|
||||
import { join } from 'vs/base/common/path';
|
||||
|
||||
export function buildTelemetryMessage(appRoot: string, extensionsPath: string): string {
|
||||
// Gets all the directories inside the extension directory
|
||||
const dirs = readdirSync(extensionsPath).filter(files => {
|
||||
// This handles case where broken symbolic links can cause statSync to throw and error
|
||||
try {
|
||||
return statSync(join(extensionsPath, files)).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
const telemetryJsonFolders: string[] = [];
|
||||
dirs.forEach((dir) => {
|
||||
const files = readdirSync(join(extensionsPath, dir)).filter(file => file === 'telemetry.json');
|
||||
// We know it contains a telemetry.json file so we add it to the list of folders which have one
|
||||
if (files.length === 1) {
|
||||
telemetryJsonFolders.push(dir);
|
||||
}
|
||||
});
|
||||
export function buildTelemetryMessage(appRoot: string, extensionsPath?: string): string {
|
||||
const mergedTelemetry = Object.create(null);
|
||||
// Simple function to merge the telemetry into one json object
|
||||
const mergeTelemetry = (contents: string, dirName: string) => {
|
||||
const telemetryData = JSON.parse(contents);
|
||||
mergedTelemetry[dirName] = telemetryData;
|
||||
};
|
||||
telemetryJsonFolders.forEach((folder) => {
|
||||
const contents = readFileSync(join(extensionsPath, folder, 'telemetry.json')).toString();
|
||||
mergeTelemetry(contents, folder);
|
||||
});
|
||||
if (extensionsPath) {
|
||||
// Gets all the directories inside the extension directory
|
||||
const dirs = readdirSync(extensionsPath).filter(files => {
|
||||
// This handles case where broken symbolic links can cause statSync to throw and error
|
||||
try {
|
||||
return statSync(join(extensionsPath, files)).isDirectory();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
const telemetryJsonFolders: string[] = [];
|
||||
dirs.forEach((dir) => {
|
||||
const files = readdirSync(join(extensionsPath, dir)).filter(file => file === 'telemetry.json');
|
||||
// We know it contains a telemetry.json file so we add it to the list of folders which have one
|
||||
if (files.length === 1) {
|
||||
telemetryJsonFolders.push(dir);
|
||||
}
|
||||
});
|
||||
telemetryJsonFolders.forEach((folder) => {
|
||||
const contents = readFileSync(join(extensionsPath, folder, 'telemetry.json')).toString();
|
||||
mergeTelemetry(contents, folder);
|
||||
});
|
||||
}
|
||||
let contents = readFileSync(join(appRoot, 'telemetry-core.json')).toString();
|
||||
mergeTelemetry(contents, 'vscode-core');
|
||||
contents = readFileSync(join(appRoot, 'telemetry-extensions.json')).toString();
|
||||
|
||||
@@ -273,8 +273,8 @@ export const editorErrorBorder = registerColor('editorError.border', { dark: nul
|
||||
export const editorWarningForeground = registerColor('editorWarning.foreground', { dark: '#CCA700', light: '#E9A700', hc: null }, nls.localize('editorWarning.foreground', 'Foreground color of warning squigglies in the editor.'));
|
||||
export const editorWarningBorder = registerColor('editorWarning.border', { dark: null, light: null, hc: Color.fromHex('#FFCC00').transparent(0.8) }, nls.localize('warningBorder', 'Border color of warning boxes in the editor.'));
|
||||
|
||||
export const editorInfoForeground = registerColor('editorInfo.foreground', { dark: '#008000', light: '#008000', hc: null }, nls.localize('editorInfo.foreground', 'Foreground color of info squigglies in the editor.'));
|
||||
export const editorInfoBorder = registerColor('editorInfo.border', { dark: null, light: null, hc: Color.fromHex('#71B771').transparent(0.8) }, nls.localize('infoBorder', 'Border color of info boxes in the editor.'));
|
||||
export const editorInfoForeground = registerColor('editorInfo.foreground', { dark: '#75BEFF', light: '#75BEFF', hc: null }, nls.localize('editorInfo.foreground', 'Foreground color of info squigglies in the editor.'));
|
||||
export const editorInfoBorder = registerColor('editorInfo.border', { dark: null, light: null, hc: Color.fromHex('#75BEFF').transparent(0.8) }, nls.localize('infoBorder', 'Border color of info boxes in the editor.'));
|
||||
|
||||
export const editorHintForeground = registerColor('editorHint.foreground', { dark: Color.fromHex('#eeeeee').transparent(0.7), light: '#6c6c6c', hc: null }, nls.localize('editorHint.foreground', 'Foreground color of hint squigglies in the editor.'));
|
||||
export const editorHintBorder = registerColor('editorHint.border', { dark: null, light: null, hc: Color.fromHex('#eeeeee').transparent(0.8) }, nls.localize('hintBorder', 'Border color of hint boxes in the editor.'));
|
||||
|
||||
@@ -18,6 +18,10 @@ export function createUpdateURL(platform: string, quality: string): string {
|
||||
return `${product.updateUrl}/api/update/${platform}/${quality}/${product.commit}`;
|
||||
}
|
||||
|
||||
export type UpdateNotAvailableClassification = {
|
||||
explicit: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
|
||||
};
|
||||
|
||||
export abstract class AbstractUpdateService implements IUpdateService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { State, IUpdate, StateType, UpdateType } from 'vs/platform/update/common
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { AbstractUpdateService, createUpdateURL } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { AbstractUpdateService, createUpdateURL, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
|
||||
export class DarwinUpdateService extends AbstractUpdateService {
|
||||
@@ -81,12 +81,10 @@ export class DarwinUpdateService extends AbstractUpdateService {
|
||||
return;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"update:downloaded" : {
|
||||
"version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:downloaded', { version: update.version });
|
||||
type UpdateDownloadedClassification = {
|
||||
version: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
};
|
||||
this.telemetryService.publicLog2<{ version: String }, UpdateDownloadedClassification>('update:downloaded', { version: update.version });
|
||||
|
||||
this.setState(State.Ready(update));
|
||||
}
|
||||
@@ -95,13 +93,7 @@ export class DarwinUpdateService extends AbstractUpdateService {
|
||||
if (this.state.type !== StateType.CheckingForUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!this.state.context });
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!this.state.context });
|
||||
|
||||
this.setState(State.Idle(UpdateType.Archive));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { State, IUpdate, AvailableForDownload, UpdateType } from 'vs/platform/up
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { createUpdateURL, AbstractUpdateService, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { shell } from 'electron';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -40,17 +40,11 @@ export class LinuxUpdateService extends AbstractUpdateService {
|
||||
}
|
||||
|
||||
this.setState(State.CheckingForUpdates(context));
|
||||
|
||||
this.requestService.request({ url: this.url }, CancellationToken.None)
|
||||
.then<IUpdate>(asJson)
|
||||
.then(update => {
|
||||
if (!update || !update.url || !update.version || !update.productVersion) {
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
|
||||
|
||||
this.setState(State.Idle(UpdateType.Archive));
|
||||
} else {
|
||||
@@ -59,14 +53,7 @@ export class LinuxUpdateService extends AbstractUpdateService {
|
||||
})
|
||||
.then(undefined, err => {
|
||||
this.logService.error(err);
|
||||
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
|
||||
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
|
||||
// only show message when explicitly checking for updates
|
||||
const message: string | undefined = !!context ? (err.message || err) : undefined;
|
||||
this.setState(State.Idle(UpdateType.Archive, message));
|
||||
|
||||
@@ -13,6 +13,7 @@ import * as path from 'vs/base/common/path';
|
||||
import { realpath, watch } from 'fs';
|
||||
import { spawn } from 'child_process';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
|
||||
abstract class AbstractUpdateService2 implements IUpdateService {
|
||||
|
||||
@@ -159,29 +160,17 @@ export class SnapUpdateService extends AbstractUpdateService2 {
|
||||
|
||||
protected doCheckForUpdates(context: any): void {
|
||||
this.setState(State.CheckingForUpdates(context));
|
||||
|
||||
this.isUpdateAvailable().then(result => {
|
||||
if (result) {
|
||||
this.setState(State.Ready({ version: 'something', productVersion: 'something' }));
|
||||
} else {
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
|
||||
|
||||
this.setState(State.Idle(UpdateType.Snap));
|
||||
}
|
||||
}, err => {
|
||||
this.logService.error(err);
|
||||
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
|
||||
this.setState(State.Idle(UpdateType.Snap, err.message || err));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { State, IUpdate, StateType, AvailableForDownload, UpdateType } from 'vs/
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { createUpdateURL, AbstractUpdateService, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
import { checksum } from 'vs/base/node/crypto';
|
||||
import { tmpdir } from 'os';
|
||||
@@ -169,12 +169,7 @@ export class Win32UpdateService extends AbstractUpdateService {
|
||||
})
|
||||
.then(undefined, err => {
|
||||
this.logService.error(err);
|
||||
/* __GDPR__
|
||||
"update:notAvailable" : {
|
||||
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
|
||||
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
|
||||
|
||||
// only show message when explicitly checking for updates
|
||||
const message: string | undefined = !!context ? (err.message || err) : undefined;
|
||||
|
||||
@@ -183,6 +183,7 @@ export interface IOpenSettings {
|
||||
forceReuseWindow?: boolean;
|
||||
diffMode?: boolean;
|
||||
addMode?: boolean;
|
||||
gotoLineMode?: boolean;
|
||||
noRecentEntry?: boolean;
|
||||
waitMarkerFileURI?: URI;
|
||||
args?: ParsedArgs;
|
||||
|
||||
@@ -132,6 +132,7 @@ export interface IOpenConfiguration {
|
||||
readonly forceEmpty?: boolean;
|
||||
readonly diffMode?: boolean;
|
||||
addMode?: boolean;
|
||||
readonly gotoLineMode?: boolean;
|
||||
readonly initialStartup?: boolean;
|
||||
readonly noRecentEntry?: boolean;
|
||||
}
|
||||
|
||||
@@ -295,6 +295,7 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
|
||||
forceReuseWindow: options.forceReuseWindow,
|
||||
diffMode: options.diffMode,
|
||||
addMode: options.addMode,
|
||||
gotoLineMode: options.gotoLineMode,
|
||||
noRecentEntry: options.noRecentEntry,
|
||||
waitMarkerFileURI: options.waitMarkerFileURI
|
||||
});
|
||||
@@ -461,10 +462,10 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
|
||||
}
|
||||
|
||||
private openFileForURI(uri: IURIToOpen): void {
|
||||
const cli = assign(Object.create(null), this.environmentService.args, { goto: true });
|
||||
const cli = assign(Object.create(null), this.environmentService.args);
|
||||
const urisToOpen = [uri];
|
||||
|
||||
this.windowsMainService.open({ context: OpenContext.API, cli, urisToOpen });
|
||||
this.windowsMainService.open({ context: OpenContext.API, cli, urisToOpen, gotoLineMode: true });
|
||||
}
|
||||
|
||||
async resolveProxy(windowId: number, url: string): Promise<string | undefined> {
|
||||
|
||||
Reference in New Issue
Block a user