diff --git a/src/vs/base/common/desktopEnvironmentInfo.ts b/src/vs/base/common/desktopEnvironmentInfo.ts new file mode 100644 index 00000000000..b6e4c107db1 --- /dev/null +++ b/src/vs/base/common/desktopEnvironmentInfo.ts @@ -0,0 +1,101 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { env } from 'vs/base/common/process'; + +// Define the enumeration for Desktop Environments +enum DesktopEnvironment { + UNKNOWN = 'UNKNOWN', + CINNAMON = 'CINNAMON', + DEEPIN = 'DEEPIN', + GNOME = 'GNOME', + KDE3 = 'KDE3', + KDE4 = 'KDE4', + KDE5 = 'KDE5', + KDE6 = 'KDE6', + PANTHEON = 'PANTHEON', + UNITY = 'UNITY', + XFCE = 'XFCE', + UKUI = 'UKUI', + LXQT = 'LXQT', +} + +const kXdgCurrentDesktopEnvVar = 'XDG_CURRENT_DESKTOP'; +const kKDESessionEnvVar = 'KDE_SESSION_VERSION'; + +export function getDesktopEnvironment(): DesktopEnvironment { + const xdgCurrentDesktop = env[kXdgCurrentDesktopEnvVar]; + if (xdgCurrentDesktop) { + const values = xdgCurrentDesktop.split(':').map(value => value.trim()).filter(value => value.length > 0); + for (const value of values) { + switch (value) { + case 'Unity': { + const desktopSessionUnity = env['DESKTOP_SESSION']; + if (desktopSessionUnity && desktopSessionUnity.includes('gnome-fallback')) { + return DesktopEnvironment.GNOME; + } + + return DesktopEnvironment.UNITY; + } + case 'Deepin': + return DesktopEnvironment.DEEPIN; + case 'GNOME': + return DesktopEnvironment.GNOME; + case 'X-Cinnamon': + return DesktopEnvironment.CINNAMON; + case 'KDE': { + const kdeSession = env[kKDESessionEnvVar]; + if (kdeSession === '5') { return DesktopEnvironment.KDE5; } + if (kdeSession === '6') { return DesktopEnvironment.KDE6; } + return DesktopEnvironment.KDE4; + } + case 'Pantheon': + return DesktopEnvironment.PANTHEON; + case 'XFCE': + return DesktopEnvironment.XFCE; + case 'UKUI': + return DesktopEnvironment.UKUI; + case 'LXQt': + return DesktopEnvironment.LXQT; + } + } + } + + const desktopSession = env['DESKTOP_SESSION']; + if (desktopSession) { + switch (desktopSession) { + case 'deepin': + return DesktopEnvironment.DEEPIN; + case 'gnome': + case 'mate': + return DesktopEnvironment.GNOME; + case 'kde4': + case 'kde-plasma': + return DesktopEnvironment.KDE4; + case 'kde': + if (kKDESessionEnvVar in env) { + return DesktopEnvironment.KDE4; + } + return DesktopEnvironment.KDE3; + case 'xfce': + case 'xubuntu': + return DesktopEnvironment.XFCE; + case 'ukui': + return DesktopEnvironment.UKUI; + } + } + + if ('GNOME_DESKTOP_SESSION_ID' in env) { + return DesktopEnvironment.GNOME; + } + if ('KDE_FULL_SESSION' in env) { + if (kKDESessionEnvVar in env) { + return DesktopEnvironment.KDE4; + } + return DesktopEnvironment.KDE3; + } + + return DesktopEnvironment.UNKNOWN; +} diff --git a/src/vs/code/node/sharedProcess/sharedProcessMain.ts b/src/vs/code/node/sharedProcess/sharedProcessMain.ts index 82b79418af0..3c0de38db43 100644 --- a/src/vs/code/node/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcess/sharedProcessMain.ts @@ -116,6 +116,8 @@ import { RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityR import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; import { SharedProcessRawConnection, SharedProcessLifecycle } from 'vs/platform/sharedProcess/common/sharedProcess'; +import { getOSReleaseInfo } from 'vs/base/node/osReleaseInfo'; +import { getDesktopEnvironment } from 'vs/base/common/desktopEnvironmentInfo'; class SharedProcessMain extends Disposable implements IClientConnectionFilter { @@ -172,6 +174,9 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { // Report Profiles Info this.reportProfilesInfo(telemetryService, userDataProfilesService); this._register(userDataProfilesService.onDidChangeProfiles(() => this.reportProfilesInfo(telemetryService, userDataProfilesService))); + + // Report Client OS/DE Info + this.reportClientOSInfo(telemetryService, logService); }); // Instantiate Contributions @@ -458,6 +463,35 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { }); } + private async reportClientOSInfo(telemetryService: ITelemetryService, logService: ILogService): Promise { + if (isLinux) { + const releaseInfo = await getOSReleaseInfo(logService.error.bind(logService)); + const desktopEnvironment = getDesktopEnvironment(); + if (releaseInfo) { + type ClientPlatformInfoClassification = { + platformId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system without any version information.' }; + platformVersionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system version excluding any name information or release code.' }; + platformIdLike: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the operating system the current OS derivate is closely related to.' }; + desktopEnvironment: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'A string identifying the desktop environment the user is using.' }; + owner: 'benibenj'; + comment: 'Provides insight into the distro and desktop environment information on Linux.'; + }; + type ClientPlatformInfoEvent = { + platformId: string; + platformVersionId: string | undefined; + platformIdLike: string | undefined; + desktopEnvironment: string | undefined; + }; + telemetryService.publicLog2('clientPlatformInfo', { + platformId: releaseInfo.id, + platformVersionId: releaseInfo.version_id, + platformIdLike: releaseInfo.id_like, + desktopEnvironment: desktopEnvironment + }); + } + } + } + handledClientConnection(e: MessageEvent): boolean { // This filter on message port messages will look for