Skip to content

Commit 367c81a

Browse files
committed
Add embedder API for candidate port filtering
1 parent 71570aa commit 367c81a

5 files changed

Lines changed: 64 additions & 8 deletions

File tree

src/vs/workbench/api/browser/mainThreadTunnelService.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
88
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
99
import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService';
1010
import { ITunnelProvider, ITunnelService, TunnelOptions } from 'vs/platform/remote/common/tunnel';
11+
import { Disposable } from 'vs/base/common/lifecycle';
1112

1213
@extHostNamedCustomer(MainContext.MainThreadTunnelService)
13-
export class MainThreadTunnelService implements MainThreadTunnelServiceShape {
14+
export class MainThreadTunnelService extends Disposable implements MainThreadTunnelServiceShape {
1415
private readonly _proxy: ExtHostTunnelServiceShape;
1516

1617
constructor(
1718
extHostContext: IExtHostContext,
1819
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
1920
@ITunnelService private readonly tunnelService: ITunnelService
2021
) {
22+
super();
2123
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTunnelService);
2224
}
2325

@@ -60,7 +62,7 @@ export class MainThreadTunnelService implements MainThreadTunnelServiceShape {
6062
}
6163

6264
async $setCandidateFilter(): Promise<void> {
63-
this.remoteExplorerService.setCandidateFilter(async (candidates: { host: string, port: number, detail: string }[]): Promise<{ host: string, port: number, detail: string }[]> => {
65+
this._register(this.remoteExplorerService.setCandidateFilter(async (candidates: { host: string, port: number, detail: string }[]): Promise<{ host: string, port: number, detail: string }[]> => {
6466
const filters: boolean[] = await this._proxy.$filterCandidates(candidates);
6567
const filteredCandidates: { host: string, port: number, detail: string }[] = [];
6668
if (filters.length !== candidates.length) {
@@ -72,10 +74,10 @@ export class MainThreadTunnelService implements MainThreadTunnelServiceShape {
7274
}
7375
}
7476
return filteredCandidates;
75-
});
77+
}));
7678
}
7779

7880
dispose(): void {
79-
//
81+
8082
}
8183
}

src/vs/workbench/contrib/remote/common/remote.contribution.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { localize } from 'vs/nls';
1717
import { joinPath } from 'vs/base/common/resources';
1818
import { Disposable } from 'vs/base/common/lifecycle';
1919
import { TunnelFactoryContribution } from 'vs/workbench/contrib/remote/common/tunnelFactory';
20+
import { ShowCandidateContribution } from 'vs/workbench/contrib/remote/common/showCandidate';
2021

2122
export const VIEWLET_ID = 'workbench.view.remote';
2223

@@ -85,3 +86,4 @@ workbenchContributionsRegistry.registerWorkbenchContribution(LabelContribution,
8586
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteChannelsContribution, LifecyclePhase.Starting);
8687
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteLogOutputChannels, LifecyclePhase.Restored);
8788
workbenchContributionsRegistry.registerWorkbenchContribution(TunnelFactoryContribution, LifecyclePhase.Ready);
89+
workbenchContributionsRegistry.registerWorkbenchContribution(ShowCandidateContribution, LifecyclePhase.Ready);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Disposable } from 'vs/base/common/lifecycle';
7+
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
8+
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
9+
import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService';
10+
11+
export class ShowCandidateContribution extends Disposable implements IWorkbenchContribution {
12+
constructor(
13+
@IRemoteExplorerService remoteExplorerService: IRemoteExplorerService,
14+
@IWorkbenchEnvironmentService workbenchEnvironmentService: IWorkbenchEnvironmentService,
15+
) {
16+
super();
17+
if (workbenchEnvironmentService.options && workbenchEnvironmentService.options.showCandidate) {
18+
this._register(remoteExplorerService.setCandidateFilter(async (candidates: { host: string, port: number, detail: string }[]): Promise<{ host: string, port: number, detail: string }[]> => {
19+
const filters: boolean[] = await Promise.all(candidates.map(candidate => workbenchEnvironmentService.options!.showCandidate!(candidate.host, candidate.port, candidate.detail)));
20+
const filteredCandidates: { host: string, port: number, detail: string }[] = [];
21+
if (filters.length !== candidates.length) {
22+
return candidates;
23+
}
24+
for (let i = 0; i < candidates.length; i++) {
25+
if (filters[i]) {
26+
filteredCandidates.push(candidates[i]);
27+
}
28+
}
29+
return filteredCandidates;
30+
}));
31+
}
32+
}
33+
}

src/vs/workbench/services/remote/common/remoteExplorerService.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
88
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
99
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
1010
import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
11-
import { Disposable } from 'vs/base/common/lifecycle';
11+
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
1212
import { IEditableData } from 'vs/workbench/common/views';
1313
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1414
import { TunnelInformation, TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
@@ -191,7 +191,7 @@ export class TunnelModel extends Disposable {
191191
this._candidateFinder = finder;
192192
}
193193

194-
setCandidateFilter(filter: (candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>): void {
194+
setCandidateFilter(filter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined): void {
195195
this._candidateFilter = filter;
196196
}
197197

@@ -235,7 +235,7 @@ export interface IRemoteExplorerService {
235235
close(remote: { host: string, port: number }): Promise<void>;
236236
setTunnelInformation(tunnelInformation: TunnelInformation | undefined): void;
237237
registerCandidateFinder(finder: () => Promise<{ host: string, port: number, detail: string }[]>): void;
238-
setCandidateFilter(filter: (candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>): void;
238+
setCandidateFilter(filter: ((candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>) | undefined): IDisposable;
239239
refresh(): Promise<void>;
240240
}
241241

@@ -310,8 +310,18 @@ class RemoteExplorerService implements IRemoteExplorerService {
310310
this.tunnelModel.registerCandidateFinder(finder);
311311
}
312312

313-
setCandidateFilter(filter: (candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>): void {
313+
setCandidateFilter(filter: (candidates: { host: string, port: number, detail: string }[]) => Promise<{ host: string, port: number, detail: string }[]>): IDisposable {
314+
if (!filter) {
315+
return {
316+
dispose: () => { }
317+
};
318+
}
314319
this.tunnelModel.setCandidateFilter(filter);
320+
return {
321+
dispose: () => {
322+
this.tunnelModel.setCandidateFilter(undefined);
323+
}
324+
};
315325
}
316326

317327
refresh(): Promise<void> {

src/vs/workbench/workbench.web.api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ interface ITunnelFactory {
5454
(tunnelOptions: TunnelOptions): Thenable<Tunnel> | undefined;
5555
}
5656

57+
interface IShowCandidate {
58+
(host: string, port: number, detail: string): Thenable<boolean>;
59+
}
60+
5761
interface IWorkbenchConstructionOptions {
5862

5963
/**
@@ -129,6 +133,11 @@ interface IWorkbenchConstructionOptions {
129133
*/
130134
readonly tunnelFactory?: ITunnelFactory;
131135

136+
/**
137+
* Support for filtering candidate ports
138+
*/
139+
readonly showCandidate?: IShowCandidate;
140+
132141
/**
133142
* Current logging level. Default is `LogLevel.Info`.
134143
*/

0 commit comments

Comments
 (0)