mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-23 15:34:20 +01:00
Browser: support tracking the host session id separately from agentic ownership
This commit is contained in:
@@ -255,13 +255,19 @@ export function matchesBrowserViewAudience(candidate: IBrowserViewAudience, patt
|
||||
&& (pattern.sessionId === undefined || pattern.sessionId === candidate.sessionId);
|
||||
}
|
||||
|
||||
/** Identifies the workbench window and optional Agents Window session that host a browser view. */
|
||||
export interface IBrowserViewHost {
|
||||
readonly windowId: number;
|
||||
readonly sessionId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary information about a browser view, including its current state and
|
||||
* ownership. Returned by the main service when listing or creating views.
|
||||
*/
|
||||
export interface IBrowserViewInfo {
|
||||
readonly id: string;
|
||||
readonly hostWindowId: number;
|
||||
readonly host: IBrowserViewHost;
|
||||
readonly owner: IBrowserViewOwner;
|
||||
readonly associatedResource?: UriComponents;
|
||||
readonly state: IBrowserViewState;
|
||||
@@ -287,7 +293,7 @@ export interface IBrowserViewCreatedEvent {
|
||||
|
||||
/** Host, ownership, storage, and initial access for a newly created browser view. */
|
||||
export interface IBrowserViewCreationContext {
|
||||
readonly hostWindowId: number;
|
||||
readonly host: IBrowserViewHost;
|
||||
readonly owner: IBrowserViewOwner;
|
||||
readonly session: BrowserViewSessionSelector;
|
||||
/** Grants automation clients access before the view is announced to other processes. */
|
||||
|
||||
@@ -7,7 +7,7 @@ import { screen, WebContentsView, webContents } from 'electron';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import { Emitter, Event } from '../../../base/common/event.js';
|
||||
import { VSBuffer } from '../../../base/common/buffer.js';
|
||||
import { IBrowserViewAudience, IBrowserViewBounds, IBrowserViewDevToolsStateEvent, IBrowserViewFocusEvent, IBrowserViewKeyDownEvent, IBrowserViewState, IBrowserViewNavigationEvent, IBrowserViewLoadingEvent, IBrowserViewLoadError, IBrowserViewTitleChangeEvent, IBrowserViewFaviconChangeEvent, IBrowserViewCaptureScreenshotOptions, IBrowserViewFindInPageOptions, IBrowserViewFindInPageResult, IBrowserViewVisibilityEvent, browserViewIsolatedWorldId, browserZoomFactors, browserZoomDefaultIndex, IBrowserViewOwner, IBrowserViewEditorOpenOptions, IBrowserViewPermissionRequestEvent, equalsBrowserViewAudience, isBrowserViewAssociatedResourceNavigation, matchesBrowserViewAudience } from '../common/browserView.js';
|
||||
import { IBrowserViewAudience, IBrowserViewBounds, IBrowserViewDevToolsStateEvent, IBrowserViewFocusEvent, IBrowserViewKeyDownEvent, IBrowserViewState, IBrowserViewNavigationEvent, IBrowserViewLoadingEvent, IBrowserViewLoadError, IBrowserViewTitleChangeEvent, IBrowserViewFaviconChangeEvent, IBrowserViewCaptureScreenshotOptions, IBrowserViewFindInPageOptions, IBrowserViewFindInPageResult, IBrowserViewVisibilityEvent, browserViewIsolatedWorldId, browserZoomFactors, browserZoomDefaultIndex, IBrowserViewOwner, IBrowserViewEditorOpenOptions, IBrowserViewPermissionRequestEvent, equalsBrowserViewAudience, isBrowserViewAssociatedResourceNavigation, matchesBrowserViewAudience, IBrowserViewHost } from '../common/browserView.js';
|
||||
import { BrowserViewEmulator } from './browserViewEmulator.js';
|
||||
import { BrowserViewInspector } from './browserViewInspector.js';
|
||||
import { IWindowsMainService } from '../../windows/electron-main/windows.js';
|
||||
@@ -123,7 +123,7 @@ export class BrowserView extends Disposable {
|
||||
|
||||
constructor(
|
||||
public readonly id: string,
|
||||
public readonly hostWindowId: number,
|
||||
public readonly host: IBrowserViewHost,
|
||||
owner: IBrowserViewOwner,
|
||||
public readonly associatedResource: URI | undefined,
|
||||
public readonly session: BrowserSession,
|
||||
@@ -167,9 +167,9 @@ export class BrowserView extends Disposable {
|
||||
this._view.setBounds({ x: 0, y: 0, width: 1024, height: 768 });
|
||||
this._view.setBackgroundColor('#FFFFFF');
|
||||
|
||||
this._ownerWindow = this.windowsMainService.getWindowById(hostWindowId)!;
|
||||
this._ownerWindow = this.windowsMainService.getWindowById(host.windowId)!;
|
||||
if (!this._ownerWindow) {
|
||||
throw new Error(`Window with ID ${hostWindowId} not found`);
|
||||
throw new Error(`Window with ID ${host.windowId} not found`);
|
||||
}
|
||||
this._register(this._ownerWindow.onDidClose(() => this.dispose()));
|
||||
this._register(this._ownerWindow.onWillLoad((e) => {
|
||||
|
||||
@@ -58,7 +58,7 @@ export class BrowserViewGroup extends Disposable implements ICDPBrowserTarget, I
|
||||
super();
|
||||
|
||||
this._register(this.browserViewMainService.onDidCreateBrowserView(({ info }) => {
|
||||
if (info.hostWindowId !== this.targetContext.hostWindowId) {
|
||||
if (info.host.windowId !== this.targetContext.host.windowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export class BrowserViewGroup extends Disposable implements ICDPBrowserTarget, I
|
||||
}
|
||||
this._isActive = true;
|
||||
|
||||
const views = await this.browserViewMainService.getBrowserViews(this.targetContext.hostWindowId);
|
||||
const views = await this.browserViewMainService.getBrowserViews(this.targetContext.host.windowId);
|
||||
await Promise.all(views.map(async info => {
|
||||
const view = this.browserViewMainService.tryGetBrowserView(info.id);
|
||||
if (view) {
|
||||
@@ -241,7 +241,7 @@ export class BrowserViewGroup extends Disposable implements ICDPBrowserTarget, I
|
||||
const view = target.view.getWebContentsView();
|
||||
const viewBounds = view.getBounds();
|
||||
return {
|
||||
windowId: this.targetContext.hostWindowId,
|
||||
windowId: this.targetContext.host.windowId,
|
||||
bounds: {
|
||||
left: viewBounds.x,
|
||||
top: viewBounds.y,
|
||||
|
||||
@@ -127,7 +127,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
private _getViewInfo(view: BrowserView): IBrowserViewInfo {
|
||||
return {
|
||||
id: view.id,
|
||||
hostWindowId: view.hostWindowId,
|
||||
host: view.host,
|
||||
owner: view.owner,
|
||||
associatedResource: view.associatedResource,
|
||||
state: view.getState()
|
||||
@@ -137,7 +137,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
async getBrowserViews(windowId?: number): Promise<IBrowserViewInfo[]> {
|
||||
const result: IBrowserViewInfo[] = [];
|
||||
for (const [, view] of this.browserViews) {
|
||||
if (windowId !== undefined && view.hostWindowId !== windowId) {
|
||||
if (windowId !== undefined && view.host.windowId !== windowId) {
|
||||
continue;
|
||||
}
|
||||
result.push(this._getViewInfo(view));
|
||||
@@ -378,7 +378,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
this._ensureWindowCloseSubscription(windowId);
|
||||
|
||||
for (const [, view] of this.browserViews) {
|
||||
if (view.hostWindowId === windowId) {
|
||||
if (view.host.windowId === windowId) {
|
||||
if (didThemeChange) {
|
||||
view.inspector.setTheme(config.theme);
|
||||
}
|
||||
@@ -426,13 +426,13 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
/**
|
||||
* Create a browser view backed by the given {@link BrowserSession}.
|
||||
*/
|
||||
private _createNativeBrowserView(id: string, hostWindowId: number, owner: IBrowserViewOwner, browserSession: BrowserSession, associatedResource?: URI, options?: Electron.WebContentsViewConstructorOptions): BrowserView {
|
||||
private _createNativeBrowserView(id: string, host: IBrowserViewCreationContext['host'], owner: IBrowserViewOwner, browserSession: BrowserSession, associatedResource?: URI, options?: Electron.WebContentsViewConstructorOptions): BrowserView {
|
||||
if (this.browserViews.has(id)) {
|
||||
throw new Error(`Browser view with id ${id} already exists`);
|
||||
}
|
||||
|
||||
browserSession.connectStorage(this.applicationStorageMainService);
|
||||
const windowConfiguration = this._windowConfigurations.get(hostWindowId);
|
||||
const windowConfiguration = this._windowConfigurations.get(host.windowId);
|
||||
if (typeof windowConfiguration?.maxHistoryEntries === 'number') {
|
||||
browserSession.history.setMaxEntries(windowConfiguration.maxHistoryEntries);
|
||||
}
|
||||
@@ -443,14 +443,14 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
const view = this.instantiationService.createInstance(
|
||||
BrowserView,
|
||||
id,
|
||||
hostWindowId,
|
||||
host,
|
||||
owner,
|
||||
associatedResource,
|
||||
browserSession,
|
||||
// Child views share their host, owner, and storage, but do not implicitly inherit agent access.
|
||||
(childOwner, url, electronOptions, editorOptions) => {
|
||||
return this._createBrowserView(generateUuid(), {
|
||||
hostWindowId,
|
||||
host,
|
||||
owner: childOwner,
|
||||
session: browserSession.id,
|
||||
initialUrl: url || undefined
|
||||
@@ -473,8 +473,8 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
}
|
||||
|
||||
private _createBrowserView(id: string, options: IBrowserViewCreateOptions, editorOpenRequest?: IBrowserViewEditorOpenOptions, electronOptions?: Electron.WebContentsViewConstructorOptions): BrowserView {
|
||||
const browserSession = this._resolveBrowserSession(id, options.hostWindowId, options.session);
|
||||
const view = this._createNativeBrowserView(id, options.hostWindowId, options.owner, browserSession, URI.revive(options.associatedResource), electronOptions);
|
||||
const browserSession = this._resolveBrowserSession(id, options.host.windowId, options.session);
|
||||
const view = this._createNativeBrowserView(id, options.host, options.owner, browserSession, URI.revive(options.associatedResource), electronOptions);
|
||||
if (options.initialAudiences) {
|
||||
view.setAudiences(options.initialAudiences);
|
||||
}
|
||||
@@ -515,7 +515,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
return;
|
||||
}
|
||||
|
||||
const windowConfiguration = this._windowConfigurations.get(view.hostWindowId);
|
||||
const windowConfiguration = this._windowConfigurations.get(view.host.windowId);
|
||||
const inspectTarget = windowConfiguration?.aiFeaturesDisabled
|
||||
? undefined
|
||||
: params.frame && await view.inspector.getElementHandle(BrowserViewInspectElementId.ContextMenuTarget, params.frame);
|
||||
@@ -526,7 +526,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
label: localize('browser.contextMenu.openLinkInNewTab', 'Open Link in New Tab'),
|
||||
click: () => {
|
||||
void this.openNew(params.linkURL, {
|
||||
hostWindowId: view.hostWindowId,
|
||||
host: view.host,
|
||||
owner: view.owner,
|
||||
session: view.session.id,
|
||||
}, { preserveFocus: true, background: true }, 'browserLinkBackground');
|
||||
@@ -556,7 +556,7 @@ export class BrowserViewMainService extends Disposable implements IBrowserViewMa
|
||||
label: localize('browser.contextMenu.openImageInNewTab', 'Open Image in New Tab'),
|
||||
click: () => {
|
||||
void this.openNew(params.srcURL!, {
|
||||
hostWindowId: view.hostWindowId,
|
||||
host: view.host,
|
||||
owner: view.owner,
|
||||
session: view.session.id,
|
||||
}, { preserveFocus: true, background: true }, 'browserLinkBackground');
|
||||
|
||||
@@ -116,7 +116,9 @@ export class PlaywrightService extends Disposable implements IPlaywrightService
|
||||
const group = await this.browserViewGroupRemoteService.createGroup(
|
||||
{ audience: { type: 'agent', sessionId } },
|
||||
{
|
||||
hostWindowId: this.windowId,
|
||||
host: {
|
||||
windowId: this.windowId
|
||||
},
|
||||
...getAgentBrowserViewCreationDefaults(sessionId)
|
||||
}
|
||||
);
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
IBrowserDeviceProfile,
|
||||
IBrowserViewPermissionRequestEvent,
|
||||
IBrowserElementSelectionState,
|
||||
IBrowserViewHost,
|
||||
} from '../../../../platform/browserView/common/browserView.js';
|
||||
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
|
||||
import { isLocalhostAuthority } from '../../../../platform/url/common/trustedDomains.js';
|
||||
@@ -361,6 +362,7 @@ export interface IBrowserViewCDPService {
|
||||
*/
|
||||
export interface IBrowserViewModel extends IDisposable {
|
||||
readonly id: string;
|
||||
readonly host: IBrowserViewHost;
|
||||
readonly owner: IBrowserViewOwner;
|
||||
readonly associatedResource: URI | undefined;
|
||||
readonly url: string;
|
||||
@@ -485,6 +487,7 @@ export class BrowserViewModel extends Disposable implements IBrowserViewModel {
|
||||
|
||||
constructor(
|
||||
readonly id: string,
|
||||
readonly host: IBrowserViewHost,
|
||||
owner: IBrowserViewOwner,
|
||||
readonly associatedResource: URI | undefined,
|
||||
initialState: IBrowserViewState,
|
||||
|
||||
@@ -30,7 +30,9 @@ export class BrowserViewCDPService extends Disposable implements IBrowserViewCDP
|
||||
return this._groupService.createGroup(
|
||||
{ browserIds: [browserId] },
|
||||
{
|
||||
hostWindowId: mainWindow.vscodeWindowId,
|
||||
host: {
|
||||
windowId: mainWindow.vscodeWindowId
|
||||
},
|
||||
owner: { type: 'user' },
|
||||
session: { scope: BrowserViewStorageScope.Ephemeral }
|
||||
}
|
||||
|
||||
+5
-3
@@ -175,7 +175,7 @@ export class BrowserViewWorkbenchService extends Disposable implements IBrowserV
|
||||
|
||||
// Listen for new browser views
|
||||
this._register(this._browserViewService.onDidCreateBrowserView(e => {
|
||||
if (e.info.hostWindowId !== this._mainWindowId) {
|
||||
if (e.info.host.windowId !== this._mainWindowId) {
|
||||
return; // Not for this window
|
||||
}
|
||||
|
||||
@@ -363,7 +363,9 @@ export class BrowserViewWorkbenchService extends Disposable implements IBrowserV
|
||||
const info = await this._browserViewService.getOrCreateBrowserView(
|
||||
id,
|
||||
{
|
||||
hostWindowId: this._mainWindowId,
|
||||
host: {
|
||||
windowId: this._mainWindowId
|
||||
},
|
||||
owner: createOptions?.owner ?? { type: 'user' },
|
||||
associatedResource,
|
||||
session: createOptions?.session ?? { scope: await this._resolveStorageScope() },
|
||||
@@ -451,7 +453,7 @@ export class BrowserViewWorkbenchService extends Disposable implements IBrowserV
|
||||
: initialUrl
|
||||
? { ...info.state, url: initialUrl }
|
||||
: info.state;
|
||||
const model = this.instantiationService.createInstance(BrowserViewModel, info.id, info.owner, associatedResource, state, this._browserViewService);
|
||||
const model = this.instantiationService.createInstance(BrowserViewModel, info.id, info.host, info.owner, associatedResource, state, this._browserViewService);
|
||||
|
||||
// Sanity: both pass and assign the model to be sure. It will no-op if already set.
|
||||
this._getOrCreateLazy({ id: info.id, associatedResource, url: initialUrl }, model).model = model;
|
||||
|
||||
Reference in New Issue
Block a user