use of io.flutter.run.daemon.FlutterApp in project flutter-intellij by flutter.
the class ObservatoryActionGroup method debugActiveHelper.
private void debugActiveHelper(@NotNull FlutterApp app, @Nullable InspectorService inspectorService) {
if (FlutterSettings.getInstance().isOpenInspectorOnAppLaunch()) {
autoActivateToolWindow();
}
final ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
if (!(toolWindowManager instanceof ToolWindowManagerEx)) {
return;
}
final ToolWindow toolWindow = toolWindowManager.getToolWindow(FlutterView.TOOL_WINDOW_ID);
if (toolWindow == null) {
return;
}
if (isDisplayingEmptyContent()) {
removeEmptyContent(toolWindow);
}
listenForRenderTreeActivations(toolWindow);
addInspector(app, inspectorService, toolWindow);
app.getVmService().addVmServiceListener(new VmServiceListenerAdapter() {
@Override
public void connectionOpened() {
onAppChanged(app);
}
@Override
public void received(String streamId, Event event) {
if (StringUtil.equals(streamId, VmService.EXTENSION_STREAM_ID)) {
if (StringUtil.equals("Flutter.Frame", event.getExtensionKind())) {
handleFlutterFrame(app);
}
}
}
@Override
public void connectionClosed() {
ApplicationManager.getApplication().invokeLater(() -> {
final ContentManager contentManager = toolWindow.getContentManager();
onAppChanged(app);
final PerAppState state = perAppViewState.remove(app);
if (state != null && state.content != null) {
contentManager.removeContent(state.content, true);
}
if (perAppViewState.isEmpty()) {
// No more applications are running.
displayEmptyContent(toolWindow);
}
});
}
});
onAppChanged(app);
app.addStateListener(new FlutterApp.FlutterAppListener() {
public void notifyAppRestarted() {
// When we get a restart finishes, queue up a notification to the flutter view
// actions. We don't notify right away because the new isolate can take a little
// while to start up. We wait until we get the first frame event, which is
// enough of an indication that the isolate and flutter framework are initialized
// enough to receive service calls (for example, calls to restore various framework
// debugging settings).
final PerAppState state = getStateForApp(app);
if (state != null) {
state.sendRestartNotificationOnNextFrame = true;
}
}
});
}
use of io.flutter.run.daemon.FlutterApp in project flutter-intellij by flutter.
the class ObservatoryActionGroup method addInspector.
private void addInspector(FlutterApp app, @Nullable InspectorService inspectorService, ToolWindow toolWindow) {
final ContentManager contentManager = toolWindow.getContentManager();
final SimpleToolWindowPanel toolWindowPanel = new SimpleToolWindowPanel(true);
final JBRunnerTabs runnerTabs = new JBRunnerTabs(myProject, ActionManager.getInstance(), null, this);
final List<FlutterDevice> existingDevices = new ArrayList<>();
for (FlutterApp otherApp : perAppViewState.keySet()) {
existingDevices.add(otherApp.device());
}
final JPanel tabContainer = new JPanel(new BorderLayout());
final Content content = contentManager.getFactory().createContent(null, app.device().getUniqueName(existingDevices), false);
tabContainer.add(runnerTabs.getComponent(), BorderLayout.CENTER);
content.setComponent(tabContainer);
content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
content.setIcon(FlutterIcons.Phone);
contentManager.addContent(content);
final PerAppState state = getOrCreateStateForApp(app);
assert (state.content == null);
state.content = content;
final DefaultActionGroup toolbarGroup = createToolbar(toolWindow, app, runnerTabs);
toolWindowPanel.setToolbar(ActionManager.getInstance().createActionToolbar("FlutterViewToolbar", toolbarGroup, true).getComponent());
// If the inspector is available (non-profile mode), then show it.
if (inspectorService != null) {
addInspectorPanel("Widgets", runnerTabs, state, InspectorService.FlutterTreeType.widget, app, inspectorService, toolWindow, toolbarGroup, true);
addInspectorPanel("Render Tree", runnerTabs, state, InspectorService.FlutterTreeType.renderObject, app, inspectorService, toolWindow, toolbarGroup, false);
} else {
toolbarGroup.add(new OverflowAction(this, app));
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar("InspectorToolbar", toolbarGroup, true);
final JComponent toolbarComponent = toolbar.getComponent();
toolbarComponent.setBorder(IdeBorderFactory.createBorder(SideBorder.BOTTOM));
tabContainer.add(toolbarComponent, BorderLayout.NORTH);
// Add a message about the inspector not being available in profile mode.
final JBLabel label = new JBLabel("Widget info not available in profile mode", SwingConstants.CENTER);
label.setForeground(UIUtil.getLabelDisabledForeground());
tabContainer.add(label, BorderLayout.CENTER);
}
final boolean isVertical = !toolWindow.getAnchor().isHorizontal();
if (isVertical) {
final JPanel dashboardsPanel = new JPanel(new BorderLayout());
tabContainer.add(dashboardsPanel, BorderLayout.SOUTH);
if (FlutterSettings.getInstance().isShowHeapDisplay()) {
dashboardsPanel.add(FPSDisplay.createJPanelView(runnerTabs, app), BorderLayout.NORTH);
dashboardsPanel.add(HeapDisplay.createJPanelView(runnerTabs, app), BorderLayout.SOUTH);
}
}
}
use of io.flutter.run.daemon.FlutterApp in project flutter-intellij by flutter.
the class SdkRunConfig method getState.
@NotNull
@Override
public LaunchState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException {
final SdkFields launchFields = fields.copy();
try {
launchFields.checkRunnable(env.getProject());
} catch (RuntimeConfigurationError e) {
throw new ExecutionException(e);
}
final MainFile mainFile = MainFile.verify(launchFields.getFilePath(), env.getProject()).get();
final Project project = env.getProject();
final RunMode mode = RunMode.fromEnv(env);
final Module module = ModuleUtil.findModuleForFile(mainFile.getFile(), env.getProject());
final LaunchState.Callback callback = (device) -> {
if (device == null)
return null;
final GeneralCommandLine command = fields.createFlutterSdkRunCommand(project, device, mode);
final FlutterApp app = FlutterApp.start(env, project, module, mode, device, command, StringUtil.capitalize(mode.mode()) + "App", "StopApp");
// Stop the app if the Flutter SDK changes.
final FlutterSdkManager.Listener sdkListener = new FlutterSdkManager.Listener() {
@Override
public void flutterSdkRemoved() {
app.shutdownAsync();
}
};
FlutterSdkManager.getInstance(project).addListener(sdkListener);
Disposer.register(project, () -> FlutterSdkManager.getInstance(project).removeListener(sdkListener));
return app;
};
final LaunchState launcher = new LaunchState(env, mainFile.getAppDir(), mainFile.getFile(), this, callback);
// Set up additional console filters.
final TextConsoleBuilder builder = launcher.getConsoleBuilder();
builder.addFilter(new DartConsoleFilter(env.getProject(), mainFile.getFile()));
if (module != null) {
builder.addFilter(new FlutterConsoleFilter(module));
}
return launcher;
}
use of io.flutter.run.daemon.FlutterApp in project flutter-intellij by flutter.
the class StackLayout method createJPanelView.
public static JPanel createJPanelView(Disposable parentDisposable, FlutterApp app) {
final JPanel panel = new JPanel(new StackLayout());
panel.setDoubleBuffered(true);
panel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP));
panel.setPreferredSize(new Dimension(100, HeapDisplay.PANEL_HEIGHT));
assert app.getPerfService() != null;
final FlutterFramesMonitor flutterFramesMonitor = app.getPerfService().getFlutterFramesMonitor();
final FPSPanel fpsPanel = new FPSPanel(flutterFramesMonitor);
final JPanel labelsPanel = new JPanel();
labelsPanel.setOpaque(false);
labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.X_AXIS));
panel.add(fpsPanel);
panel.add(labelsPanel);
final JBLabel fpsLabel = new JBLabel();
fpsLabel.setAlignmentY(Component.TOP_ALIGNMENT);
fpsLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
fpsLabel.setForeground(UIUtil.getLabelDisabledForeground());
fpsLabel.setOpaque(false);
fpsLabel.setBorder(JBUI.Borders.empty(4));
final JBLabel elapsedLabel = new JBLabel("", SwingConstants.RIGHT);
elapsedLabel.setAlignmentY(Component.TOP_ALIGNMENT);
elapsedLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
elapsedLabel.setForeground(UIUtil.getLabelDisabledForeground());
elapsedLabel.setOpaque(false);
elapsedLabel.setBorder(JBUI.Borders.empty(4));
labelsPanel.add(fpsLabel);
labelsPanel.add(Box.createHorizontalGlue());
labelsPanel.add(elapsedLabel);
final FlutterFramesMonitor.Listener listener = event -> {
fpsPanel.update();
final int ms = Math.round(event.elapsedMicros / 1000.0f);
elapsedLabel.setText(ms + "ms");
SwingUtilities.invokeLater(elapsedLabel::repaint);
fpsLabel.setText(df.format(flutterFramesMonitor.getFPS()) + " FPS");
SwingUtilities.invokeLater(fpsLabel::repaint);
};
flutterFramesMonitor.addListener(listener);
Disposer.register(parentDisposable, () -> flutterFramesMonitor.removeListener(listener));
return panel;
}
use of io.flutter.run.daemon.FlutterApp in project flutter-intellij by flutter.
the class FlutterReloadManager method handleSaveAllNotification.
private void handleSaveAllNotification(@Nullable Editor editor) {
if (!mySettings.isReloadOnSave() || editor == null) {
return;
}
if (handlingSave.get()) {
return;
}
final AnAction reloadAction = ProjectActions.getAction(myProject, ReloadFlutterApp.ID);
final FlutterApp app = getApp(reloadAction);
if (app == null) {
return;
}
if (!app.isStarted() || app.isReloading()) {
return;
}
if (!(editor instanceof EditorEx)) {
return;
}
final EditorEx editorEx = (EditorEx) editor;
final VirtualFile file = editorEx.getVirtualFile();
// Add an arbitrary 125ms delay to allow analysis to catch up. This delay gives the analysis server a
// small pause to return error results in the (relatively infrequent) case where the user makes a bad
// edit and immediately hits save.
final int reloadDelayMs = 125;
handlingSave.set(true);
JobScheduler.getScheduler().schedule(() -> {
if (hasErrors(app.getProject(), app.getModule(), editor.getDocument())) {
handlingSave.set(false);
showAnalysisNotification("Reload not performed", "Analysis issues found", true);
} else {
final Notification notification = showRunNotification(app, null, "Reloading…", false);
app.performHotReload(supportsPauseAfterReload()).thenAccept(result -> {
notification.expire();
if (!result.ok()) {
showRunNotification(app, "Hot Reload Error", result.getMessage(), true);
} else if (result.isRestartRecommended()) {
showRunNotification(app, "Reloading…", RESTART_SUGGESTED_TEXT, false);
}
}).whenComplete((aVoid, throwable) -> handlingSave.set(false));
}
}, reloadDelayMs, TimeUnit.MILLISECONDS);
}
Aggregations