forked from flutter/flutter-intellij
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFlutterDebugProcess.java
More file actions
152 lines (134 loc) · 6 KB
/
FlutterDebugProcess.java
File metadata and controls
152 lines (134 loc) · 6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright 2016 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.run;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Computable;
import com.intellij.ui.content.Content;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.jetbrains.lang.dart.util.DartUrlResolver;
import io.flutter.FlutterUtils;
import io.flutter.actions.ReloadAllFlutterApps;
import io.flutter.actions.ReloadFlutterApp;
import io.flutter.actions.RestartAllFlutterApps;
import io.flutter.actions.RestartFlutterApp;
import io.flutter.logging.PluginLogger;
import io.flutter.run.common.RunMode;
import io.flutter.run.daemon.FlutterApp;
import io.flutter.view.FlutterViewMessages;
import io.flutter.vmService.DartVmServiceDebugProcess;
import org.dartlang.vm.service.VmService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* A debug process that handles hot reloads for Flutter.
* <p>
* It's used for both the 'Run' and 'Debug' modes. (We apparently need a debug process even
* when not debugging in order to support hot reload.)
*/
public class FlutterDebugProcess extends DartVmServiceDebugProcess {
private static final @NotNull Logger LOG = PluginLogger.createLogger(FlutterDebugProcess.class);
private final @NotNull FlutterApp app;
public FlutterDebugProcess(@NotNull FlutterApp app,
@NotNull ExecutionEnvironment executionEnvironment,
@NotNull XDebugSession session,
@NotNull ExecutionResult executionResult,
@NotNull DartUrlResolver dartUrlResolver,
@NotNull PositionMapper mapper) {
super(executionEnvironment, session, executionResult, dartUrlResolver, app.getConnector(), mapper);
this.app = app;
}
@Override
protected void onVmConnected(@NotNull VmService vmService) {
app.setFlutterDebugProcess(this);
FlutterViewMessages.sendDebugActive(getSession().getProject(), app, vmService);
}
@Override
public void registerAdditionalActions(@NotNull final DefaultActionGroup leftToolbar,
@NotNull final DefaultActionGroup topToolbar,
@NotNull final DefaultActionGroup settings) {
if (app.getMode() != RunMode.DEBUG) {
// Remove the debug-specific actions that aren't needed when we're not debugging.
// Remove all but specified actions.
final AnAction[] leftActions = leftToolbar.getChildActionsOrStubs();
// Not all on the classpath so we resort to Strings.
final List<String> actionClassNames = Arrays
.asList("com.intellij.execution.actions.StopAction", "com.intellij.ui.content.tabs.PinToolwindowTabAction",
"com.intellij.execution.ui.actions.CloseAction", "com.intellij.ide.actions.ContextHelpAction");
for (AnAction a : leftActions) {
if (!actionClassNames.contains(a.getClass().getName())) {
leftToolbar.remove(a);
}
}
// Remove all top actions.
final AnAction[] topActions = topToolbar.getChildActionsOrStubs();
for (AnAction action : topActions) {
topToolbar.remove(action);
}
// Remove all settings actions.
final AnAction[] settingsActions = settings.getChildActionsOrStubs();
for (AnAction a : settingsActions) {
settings.remove(a);
}
}
// Add actions common to the run and debug windows.
final Computable<Boolean> isSessionActive = () -> app.isStarted() && getVmConnected() && !getSession().isStopped();
final Computable<Boolean> canReload = () -> app.getLaunchMode().supportsReload() && isSessionActive.compute() && !app.isReloading();
final Computable<Boolean> debugUrlAvailable = () -> isSessionActive.compute() && app.getConnector().getBrowserUrl() != null;
if (app.getMode() == RunMode.DEBUG) {
topToolbar.addSeparator();
topToolbar.addAction(new FlutterPopFrameAction());
}
topToolbar.addSeparator();
topToolbar.addAction(new ReloadFlutterApp(app, canReload));
topToolbar.addAction(new RestartFlutterApp(app, canReload));
topToolbar.addSeparator();
topToolbar.addAction(new OpenDevToolsAction(app, debugUrlAvailable));
FlutterDebugProcessActions.addTopToolbarExtensionActions(topToolbar);
settings.addAction(new ReloadAllFlutterApps(app, canReload));
settings.addAction(new RestartAllFlutterApps(app, canReload));
// Don't call super since we have our own observatory action.
}
@Override
public void sessionInitialized() {
if (app.getMode() != RunMode.DEBUG) {
suppressDebugViews(getSession().getUI());
}
}
/**
* Turn off debug-only views (variables and frames).
*/
private static void suppressDebugViews(@Nullable RunnerLayoutUi ui) {
if (ui == null) {
return;
}
final String name = XDebuggerBundle.message("debugger.session.tab.console.content.name");
for (Content c : ui.getContents()) {
if (c != null && !Objects.equals(c.getTabName(), name)) {
try {
var application = ApplicationManager.getApplication();
if (application != null) {
application.invokeAndWait(() -> ui.removeContent(c, false /* dispose? */));
}
}
catch (ProcessCanceledException e) {
FlutterUtils.warn(LOG, "ProcessCanceledException in suppressDebugViews", e, true);
throw e;
}
}
}
}
}