diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0a2309b566877..939d77562e3a8 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -147,6 +147,11 @@ declare module 'vscode' { * Note that these are of type TunnelDescription and cannot be disposed. */ export let tunnels: Thenable; + + /** + * Fired when the list of tunnels has changed. + */ + export const onDidTunnelsChange: Event; } export interface ResourceLabelFormatter { diff --git a/src/vs/workbench/api/browser/mainThreadTunnelService.ts b/src/vs/workbench/api/browser/mainThreadTunnelService.ts index 57718a1cbbb9f..cc55545aea2ab 100644 --- a/src/vs/workbench/api/browser/mainThreadTunnelService.ts +++ b/src/vs/workbench/api/browser/mainThreadTunnelService.ts @@ -22,6 +22,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun ) { super(); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTunnelService); + this._register(tunnelService.onTunnelOpened(() => this._proxy.$onDidTunnelsChange())); + this._register(tunnelService.onTunnelClosed(() => this._proxy.$onDidTunnelsChange())); } async $openTunnel(tunnelOptions: TunnelOptions): Promise { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index fa2f702323b39..76aa93aab1ce2 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -765,6 +765,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, get tunnels() { return extHostTunnelService.getTunnels(); + }, + onDidTunnelsChange: (listener, thisArg?, disposables?) => { + return extHostTunnelService.onDidTunnelsChange(listener, thisArg, disposables); } }; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 7c62fad573d32..ff5a245e7ed89 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1423,6 +1423,7 @@ export interface ExtHostTunnelServiceShape { $filterCandidates(candidates: { host: string, port: number, detail: string }[]): Promise; $forwardPort(tunnelOptions: TunnelOptions): Promise | undefined; $closeTunnel(remote: { host: string, port: number }): Promise; + $onDidTunnelsChange(): Promise; } // --- proxy identifiers diff --git a/src/vs/workbench/api/common/extHostTunnelService.ts b/src/vs/workbench/api/common/extHostTunnelService.ts index d92b8be4daf58..6e5e59dd044c0 100644 --- a/src/vs/workbench/api/common/extHostTunnelService.ts +++ b/src/vs/workbench/api/common/extHostTunnelService.ts @@ -8,6 +8,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import type * as vscode from 'vscode'; import { RemoteTunnel, TunnelOptions } from 'vs/platform/remote/common/tunnel'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { Emitter } from 'vs/base/common/event'; export interface TunnelDto { remoteAddress: { port: number, host: string }; @@ -32,6 +33,7 @@ export interface IExtHostTunnelService extends ExtHostTunnelServiceShape { readonly _serviceBrand: undefined; openTunnel(forward: TunnelOptions): Promise; getTunnels(): Promise; + onDidTunnelsChange: vscode.Event; setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise; } @@ -39,6 +41,8 @@ export const IExtHostTunnelService = createDecorator('IEx export class ExtHostTunnelService implements IExtHostTunnelService { _serviceBrand: undefined; + onDidTunnelsChange: vscode.Event = (new Emitter()).event; + async openTunnel(forward: TunnelOptions): Promise { return undefined; } @@ -54,5 +58,5 @@ export class ExtHostTunnelService implements IExtHostTunnelService { async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise { return { dispose: () => { } }; } $forwardPort(tunnelOptions: TunnelOptions): Promise | undefined { return undefined; } async $closeTunnel(remote: { host: string, port: number }): Promise { } - + async $onDidTunnelsChange(): Promise { } } diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index 9af73f1b77008..8930d91e856e0 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -39,6 +39,8 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe private _forwardPortProvider: ((tunnelOptions: TunnelOptions) => Thenable | undefined) | undefined; private _showCandidatePort: (host: string, port: number, detail: string) => Thenable = () => { return Promise.resolve(true); }; private _extensionTunnels: Map> = new Map(); + private _onDidTunnelsChange: Emitter = new Emitter(); + onDidTunnelsChange: vscode.Event = this._onDidTunnelsChange.event; constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, @@ -104,6 +106,10 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe } } + async $onDidTunnelsChange(): Promise { + this._onDidTunnelsChange.fire(); + } + $forwardPort(tunnelOptions: TunnelOptions): Promise | undefined { if (this._forwardPortProvider) { const providedPort = this._forwardPortProvider!(tunnelOptions);