Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ide feature #7108

Merged
merged 5 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions flutter-idea/src/io/flutter/devtools/DevToolsIdeFeature.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2023 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package io.flutter.devtools;

/**
* This identifies from what feature DevTools is started. See https://github.com/flutter/flutter-intellij/issues/7100 for details.
*/
public enum DevToolsIdeFeature {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Add a URL reference here or in DevToolsUrl.java that points to #7100 for documentation.

ON_DEBUG_AUTOMATIC("onDebugAutomatic"),
RUN_CONSOLE("runConsole"),
TOOL_WINDOW("toolWindow");

public final String value;

DevToolsIdeFeature(String value) {
this.value = value;
}
}
14 changes: 10 additions & 4 deletions flutter-idea/src/io/flutter/devtools/DevToolsUrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class DevToolsUrl {

private final boolean canUseDevToolsPathUrl;

public final DevToolsIdeFeature ideFeature;

public DevToolsUrl(String devtoolsHost,
int devtoolsPort,
String vmServiceUri,
Expand All @@ -38,8 +40,9 @@ public DevToolsUrl(String devtoolsHost,
String colorHexCode,
Float fontSize,
@Nullable FlutterSdkVersion flutterSdkVersion,
WorkspaceCache workspaceCache) {
this(devtoolsHost, devtoolsPort, vmServiceUri, page, embed, colorHexCode, fontSize, flutterSdkVersion, workspaceCache, new FlutterSdkUtil());
WorkspaceCache workspaceCache,
DevToolsIdeFeature ideFeature) {
this(devtoolsHost, devtoolsPort, vmServiceUri, page, embed, colorHexCode, fontSize, flutterSdkVersion, workspaceCache, ideFeature, new FlutterSdkUtil());
}


Expand All @@ -52,6 +55,7 @@ public DevToolsUrl(String devtoolsHost,
Float fontSize,
FlutterSdkVersion flutterSdkVersion,
WorkspaceCache workspaceCache,
DevToolsIdeFeature ideFeature,
FlutterSdkUtil flutterSdkUtil) {
this.devtoolsHost = devtoolsHost;
this.devtoolsPort = devtoolsPort;
Expand All @@ -61,6 +65,7 @@ public DevToolsUrl(String devtoolsHost,
this.colorHexCode = colorHexCode;
this.fontSize = fontSize;
this.flutterSdkVersion = flutterSdkVersion;
this.ideFeature = ideFeature;
this.sdkUtil = flutterSdkUtil;

if (workspaceCache != null && workspaceCache.isBazel()) {
Expand Down Expand Up @@ -90,12 +95,13 @@ public String getUrlString() {
if (fontSize != null) {
params.add("fontSize=" + fontSize);
}

if (ideFeature != null) {
params.add("ideFeature=" + ideFeature.value);
}
if (vmServiceUri != null) {
final String urlParam = URLEncoder.encode(vmServiceUri, StandardCharsets.UTF_8);
params.add("uri=" + urlParam);
}

if (widgetId != null) {
params.add("inspectorRef=" + widgetId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ private void addPerformanceViewContent(FlutterApp app, ToolWindow toolWindow) {

FlutterSdk flutterSdk = FlutterSdk.getFlutterSdk(app.getProject());
BrowserLauncher.getInstance().browse(
(new DevToolsUrl(instance.host, instance.port, app.getConnector().getBrowserUrl(), null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(app.getProject()))).getUrlString(),
(new DevToolsUrl(instance.host, instance.port, app.getConnector().getBrowserUrl(), null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(app.getProject()), null)).getUrlString(),
null
);
});
Expand Down
3 changes: 2 additions & 1 deletion flutter-idea/src/io/flutter/run/OpenDevToolsAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.flutter.FlutterInitializer;
import io.flutter.ObservatoryConnector;
import io.flutter.bazel.WorkspaceCache;
import io.flutter.devtools.DevToolsIdeFeature;
import io.flutter.devtools.DevToolsUrl;
import io.flutter.run.daemon.DevToolsService;
import io.flutter.run.daemon.FlutterApp;
Expand Down Expand Up @@ -79,7 +80,7 @@ public void actionPerformed(@NotNull final AnActionEvent event) {

FlutterSdk flutterSdk = FlutterSdk.getFlutterSdk(project);
BrowserLauncher.getInstance().browse(
(new DevToolsUrl(instance.host, instance.port, serviceUrl, null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(project)).getUrlString()),
(new DevToolsUrl(instance.host, instance.port, serviceUrl, null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(project), DevToolsIdeFeature.RUN_CONSOLE).getUrlString()),
null
);
});
Expand Down
63 changes: 27 additions & 36 deletions flutter-idea/src/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import io.flutter.FlutterInitializer;
import io.flutter.FlutterUtils;
import io.flutter.bazel.WorkspaceCache;
import io.flutter.devtools.DevToolsIdeFeature;
import io.flutter.devtools.DevToolsUrl;
import io.flutter.inspector.DiagnosticsNode;
import io.flutter.inspector.InspectorGroupManagerService;
Expand Down Expand Up @@ -243,6 +244,7 @@ private void addBrowserInspectorViewContent(FlutterApp app,
@Nullable InspectorService inspectorService,
ToolWindow toolWindow,
boolean isEmbedded,
boolean openOnAppLaunch,
DevToolsInstance devToolsInstance) {
assert(SwingUtilities.isEventDispatchThread());

Expand Down Expand Up @@ -275,7 +277,8 @@ private void addBrowserInspectorViewContent(FlutterApp app,
color,
UIUtil.getFontSize(UIUtil.FontSize.NORMAL),
flutterSdkVersion,
WorkspaceCache.getInstance(app.getProject())
WorkspaceCache.getInstance(app.getProject()),
openOnAppLaunch ? DevToolsIdeFeature.ON_DEBUG_AUTOMATIC : DevToolsIdeFeature.TOOL_WINDOW
Copy link
Member

@kenzieschmoll kenzieschmoll Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible that a user can have the openOnAppLaunch setting on, and also manually open the Inspector tool window? I would think we would only want ON_DEBUG_AUTOMATIC if a user did not manually open the tool window.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah a user could open their project, and then before they run their app open the inspector tool window. I can change how we're setting openOnAppLaunch to only be true if the tool window was automatically opened.

);

//noinspection CodeBlock2Expr
Expand All @@ -284,7 +287,7 @@ private void addBrowserInspectorViewContent(FlutterApp app,
// If the embedded browser doesn't work, offer a link to open in the regular browser.
final List<LabelInput> inputs = Arrays.asList(
new LabelInput("The embedded browser failed to load. Error: " + error),
openDevToolsLabel(app, inspectorService, toolWindow)
openDevToolsLabel(app, inspectorService, toolWindow, openOnAppLaunch)
);
presentClickableLabel(toolWindow, inputs);
}));
Expand All @@ -304,7 +307,7 @@ private void addBrowserInspectorViewContent(FlutterApp app,
} else {
BrowserLauncher.getInstance().browse(
(new DevToolsUrl(devToolsInstance.host, devToolsInstance.port, browserUrl, "inspector", false, null, null,
flutterSdkVersion, WorkspaceCache.getInstance(app.getProject())).getUrlString()),
flutterSdkVersion, WorkspaceCache.getInstance(app.getProject()), openOnAppLaunch ? DevToolsIdeFeature.ON_DEBUG_AUTOMATIC : DevToolsIdeFeature.TOOL_WINDOW).getUrlString()),
null
);
presentLabel(toolWindow, "DevTools inspector has been opened in the browser.");
Expand Down Expand Up @@ -486,19 +489,15 @@ public void debugActive(@NotNull FlutterViewMessages.FlutterDebugEvent event) {
}
}

protected void handleJxBrowserInstalled(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow) {
presentDevTools(app, inspectorService, toolWindow, true);
}

private void presentDevTools(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded) {
private void presentDevTools(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded, boolean openOnAppLaunch) {
verifyEventDispatchThread();

devToolsInstallCount += 1;
presentLabel(toolWindow, getInstallingDevtoolsLabel());

openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded);
openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded, openOnAppLaunch);

setUpToolWindowListener(app, inspectorService, toolWindow, isEmbedded);
setUpToolWindowListener(app, inspectorService, toolWindow, isEmbedded, openOnAppLaunch);
}

@VisibleForTesting
Expand All @@ -507,14 +506,14 @@ protected void verifyEventDispatchThread() {
}

@VisibleForTesting
protected void setUpToolWindowListener(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded) {
protected void setUpToolWindowListener(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded, boolean openOnAppLaunch) {
if (this.toolWindowListener == null) {
this.toolWindowListener = new FlutterViewToolWindowManagerListener(myProject, toolWindow);
}
this.toolWindowListener.updateOnWindowOpen(() -> {
devToolsInstallCount += 1;
presentLabel(toolWindow, getInstallingDevtoolsLabel());
openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded, true);
openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded, openOnAppLaunch, true);
});
}

Expand All @@ -524,14 +523,15 @@ private String getInstallingDevtoolsLabel() {
}

@VisibleForTesting
protected void openInspectorWithDevTools(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded) {
openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded, false);
protected void openInspectorWithDevTools(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean isEmbedded, boolean openOnAppLaunch) {
openInspectorWithDevTools(app, inspectorService, toolWindow, isEmbedded, openOnAppLaunch, false);
}

private void openInspectorWithDevTools(FlutterApp app,
InspectorService inspectorService,
ToolWindow toolWindow,
boolean isEmbedded,
boolean openOnAppLaunch,
boolean forceDevToolsRestart) {
AsyncUtils.whenCompleteUiThread(
forceDevToolsRestart
Expand All @@ -555,14 +555,14 @@ private void openInspectorWithDevTools(FlutterApp app,
return;
}

addBrowserInspectorViewContent(app, inspectorService, toolWindow, isEmbedded, instance);
addBrowserInspectorViewContent(app, inspectorService, toolWindow, isEmbedded, openOnAppLaunch, instance);
}
);
}

private LabelInput openDevToolsLabel(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow) {
private LabelInput openDevToolsLabel(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean openOnAppLaunch) {
return new LabelInput("Open DevTools in the browser?", (linkLabel, data) -> {
presentDevTools(app, inspectorService, toolWindow, false);
presentDevTools(app, inspectorService, toolWindow, false, openOnAppLaunch);
});
}

Expand Down Expand Up @@ -595,16 +595,6 @@ protected void presentClickableLabel(ToolWindow toolWindow, List<LabelInput> lab
replacePanelLabel(toolWindow, center);
}

protected void presentOpenDevToolsOptionWithMessage(FlutterApp app,
InspectorService inspectorService,
ToolWindow toolWindow,
String message) {
final List<LabelInput> inputs = new ArrayList<>();
inputs.add(new LabelInput(message));
inputs.add(openDevToolsLabel(app, inspectorService, toolWindow));
presentClickableLabel(toolWindow, inputs);
}

private void replacePanelLabel(ToolWindow toolWindow, JComponent label) {
ApplicationManager.getApplication().invokeLater(() -> {
final ContentManager contentManager = toolWindow.getContentManager();
Expand All @@ -631,12 +621,13 @@ private void debugActiveHelper(FlutterApp app, @Nullable InspectorService inspec
return;
}

final boolean openOnAppLaunch = FlutterSettings.getInstance().isOpenInspectorOnAppLaunch();
if (toolWindow.isAvailable()) {
updateToolWindowVisibility(toolWindow);
updateToolWindowVisibility(toolWindow, openOnAppLaunch);
}
else {
toolWindow.setAvailable(true, () -> {
updateToolWindowVisibility(toolWindow);
updateToolWindowVisibility(toolWindow, openOnAppLaunch);
});
}

Expand All @@ -649,21 +640,21 @@ private void debugActiveHelper(FlutterApp app, @Nullable InspectorService inspec
toolWindow.setIcon(ExecutionUtil.getLiveIndicator(FlutterIcons.Flutter_13));

if (toolWindow.isVisible()) {
displayEmbeddedBrowser(app, inspectorService, toolWindow);
displayEmbeddedBrowser(app, inspectorService, toolWindow, openOnAppLaunch);
}
else {
if (toolWindowListener == null) {
toolWindowListener = new FlutterViewToolWindowManagerListener(myProject, toolWindow);
}
// If the window isn't visible yet, only executed embedded browser steps when it becomes visible.
toolWindowListener.updateOnWindowFirstVisible(() -> {
displayEmbeddedBrowser(app, inspectorService, toolWindow);
displayEmbeddedBrowser(app, inspectorService, toolWindow, openOnAppLaunch);
});
}
}

private void displayEmbeddedBrowser(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow) {
presentDevTools(app, inspectorService, toolWindow, true);
private void displayEmbeddedBrowser(FlutterApp app, InspectorService inspectorService, ToolWindow toolWindow, boolean openOnAppLaunch) {
presentDevTools(app, inspectorService, toolWindow, true, openOnAppLaunch);
}

private void updateForEmptyContent(ToolWindow toolWindow) {
Expand Down Expand Up @@ -765,12 +756,12 @@ private void onAppChanged(FlutterApp app) {
}
}

private void updateToolWindowVisibility(ToolWindow flutterToolWindow) {
private void updateToolWindowVisibility(ToolWindow flutterToolWindow, boolean openOnAppLaunch) {
if (flutterToolWindow.isVisible()) {
return;
}

if (FlutterSettings.getInstance().isOpenInspectorOnAppLaunch()) {
if (openOnAppLaunch) {
flutterToolWindow.show(null);
}
}
Expand Down Expand Up @@ -802,7 +793,7 @@ public void perform(AnActionEvent event) {

FlutterSdk flutterSdk = FlutterSdk.getFlutterSdk(app.getProject());
BrowserLauncher.getInstance().browse(
(new DevToolsUrl(instance.host, instance.port, urlString, null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(app.getProject())).getUrlString()),
(new DevToolsUrl(instance.host, instance.port, urlString, null, false, null, null, flutterSdk == null ? null : flutterSdk.getVersion(), WorkspaceCache.getInstance(app.getProject()), null).getUrlString()),
null
);
});
Expand Down
25 changes: 15 additions & 10 deletions flutter-idea/testSrc/unit/io/flutter/devtools/DevToolsUrlTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,55 +29,60 @@ public void testGetUrlString() {
FlutterSdkVersion newVersion = new FlutterSdkVersion("3.3.0");
assertEquals(
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, newVersion, notBazelWorkspaceCache, mockSdkUtil)).getUrlString()
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil)).getUrlString()
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&embed=true&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, true, null, null, newVersion, notBazelWorkspaceCache, mockSdkUtil)).getUrlString()
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, true, null, null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil)).getUrlString()
);

assertEquals(
"http://127.0.0.1:9100/?ide=IntelliJ-IDEA",
(new DevToolsUrl(devtoolsHost, devtoolsPort, null, null, false, null, null, newVersion, notBazelWorkspaceCache, mockSdkUtil).getUrlString())
(new DevToolsUrl(devtoolsHost, devtoolsPort, null, null, false, null, null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil).getUrlString())
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&backgroundColor=ffffff&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "ffffff", null, newVersion, notBazelWorkspaceCache, mockSdkUtil).getUrlString())
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "ffffff", null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil).getUrlString())
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=IntelliJ-IDEA&backgroundColor=ffffff&fontSize=12.0&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "ffffff", 12.0f, newVersion, notBazelWorkspaceCache, mockSdkUtil).getUrlString())
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "ffffff", 12.0f, newVersion, notBazelWorkspaceCache, null, mockSdkUtil).getUrlString())
);

when(mockSdkUtil.getFlutterHostEnvValue()).thenReturn("Android-Studio");

assertEquals(
"http://127.0.0.1:9100/timeline?ide=Android-Studio&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, newVersion, notBazelWorkspaceCache, mockSdkUtil).getUrlString())
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil).getUrlString())
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=Android-Studio&backgroundColor=3c3f41&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "3c3f41", null, newVersion, notBazelWorkspaceCache, mockSdkUtil).getUrlString())
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, "3c3f41", null, newVersion, notBazelWorkspaceCache, null, mockSdkUtil).getUrlString())
);

FlutterSdkVersion oldVersion = new FlutterSdkVersion("3.0.0");
assertEquals(
"http://127.0.0.1:9100/#/?ide=Android-Studio&page=timeline&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, oldVersion, notBazelWorkspaceCache, mockSdkUtil)).getUrlString()
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, oldVersion, notBazelWorkspaceCache, null, mockSdkUtil)).getUrlString()
);

assertEquals(
"http://127.0.0.1:9100/#/?ide=Android-Studio&page=timeline&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, null, notBazelWorkspaceCache, mockSdkUtil)).getUrlString()
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, null, notBazelWorkspaceCache, null, mockSdkUtil)).getUrlString()
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=Android-Studio&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, null, bazelWorkspaceCache, mockSdkUtil)).getUrlString()
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, null, bazelWorkspaceCache, null, mockSdkUtil)).getUrlString()
);

assertEquals(
"http://127.0.0.1:9100/timeline?ide=Android-Studio&ideFeature=toolWindow&uri=http%3A%2F%2F127.0.0.1%3A50224%2FWTFTYus3IPU%3D%2F",
(new DevToolsUrl(devtoolsHost, devtoolsPort, serviceProtocolUri, page, false, null, null, null, bazelWorkspaceCache, DevToolsIdeFeature.TOOL_WINDOW, mockSdkUtil)).getUrlString()
);
}
}