IDEA-85676 add logcat to debugger session tab

This commit is contained in:
Eugene Kudelevsky
2012-11-01 19:29:23 +04:00
parent 19c2fd61eb
commit 53348aaeda
8 changed files with 291 additions and 129 deletions
@@ -79,6 +79,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
private LogFilterModel myModel;
private final List<LogConsoleListener> myListeners = new ArrayList<LogConsoleListener>();
private final List<? extends LogFilter> myFilters;
private FilterComponent myFilter = new FilterComponent("LOG_FILTER_HISTORY", 5) {
public void filter() {
@@ -100,6 +101,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
myProject = project;
myTitle = title;
myModel = model;
myFilters = myModel.getLogFilters();
myReaderThread = new ReaderThread(reader);
myBuildInActions = buildInActions;
TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
@@ -215,6 +217,7 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
return;
}
if (isActive() && !readerThread.myRunning) {
resetLogFilter();
myFilter.setSelectedItem(myModel.getCustomFilter());
readerThread.startRunning();
ApplicationManager.getApplication().executeOnPooledThread(readerThread);
@@ -476,14 +479,8 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
}
public JComponent getSearchComponent() {
List<? extends LogFilter> filters = myModel.getLogFilters();
myLogFilterCombo.setModel(new DefaultComboBoxModel(filters.toArray(new LogFilter[filters.size()])));
for (LogFilter filter : filters) {
if (myModel.isFilterSelected(filter)) {
myLogFilterCombo.setSelectedItem(filter);
break;
}
}
myLogFilterCombo.setModel(new DefaultComboBoxModel(myFilters.toArray(new LogFilter[myFilters.size()])));
resetLogFilter();
myLogFilterCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final LogFilter filter = (LogFilter)myLogFilterCombo.getSelectedItem();
@@ -501,6 +498,15 @@ public abstract class LogConsoleBase extends AdditionalTabComponent implements L
return mySearchComponent;
}
private void resetLogFilter() {
for (LogFilter filter : myFilters) {
if (myModel.isFilterSelected(filter)) {
myLogFilterCombo.setSelectedItem(filter);
break;
}
}
}
@NotNull
protected Component getTextFilterComponent() {
return myFilter;
@@ -21,6 +21,7 @@ import com.intellij.diagnostic.logging.LogFilter;
import com.intellij.diagnostic.logging.LogFilterListener;
import com.intellij.diagnostic.logging.LogFilterModel;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
@@ -47,19 +48,15 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
private boolean myFullMessageApplicableByCustomFilter = false;
private StringBuilder myMessageBuilder = new StringBuilder();
private LogFilter mySelectedLogFilter;
private List<AndroidLogFilter> myLogFilters = new ArrayList<AndroidLogFilter>();
protected List<AndroidLogFilter> myLogFilters = new ArrayList<AndroidLogFilter>();
public AndroidLogFilterModel(String initialLogLevelName) {
public AndroidLogFilterModel() {
for (Log.LogLevel logLevel : Log.LogLevel.values()) {
AndroidLogFilter filter = new AndroidLogFilter(logLevel);
if (logLevel.name().equals(initialLogLevelName)) {
mySelectedLogFilter = filter;
}
myLogFilters.add(filter);
myLogFilters.add(new AndroidLogFilter(logLevel));
}
}
public void updateCustomFilter(String filter) {
super.updateCustomFilter(filter);
setCustomFilter(filter);
@@ -81,7 +78,7 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
return null;
}
protected abstract void saveLogLevel(Log.LogLevel logLevel);
protected abstract void saveLogLevel(String logLevelName);
public void addFilterListener(LogFilterListener listener) {
myListeners.add(listener);
@@ -124,11 +121,8 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
@Override
public boolean isApplicable(String text) {
if (!super.isApplicable(text)) return false;
if (!(mySelectedLogFilter == null || mySelectedLogFilter.isAcceptable(text))) {
return false;
}
return true;
final LogFilter selectedLogLevelFilter = getSelectedLogLevelFilter();
return selectedLogLevelFilter == null || selectedLogLevelFilter.isAcceptable(text);
}
public boolean isApplicableByCustomFilter(String text) {
@@ -207,7 +201,7 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
}
@Nullable
private static Log.LogLevel getLogLevel(@NotNull String name) {
protected static Log.LogLevel getLogLevel(@NotNull String name) {
for (Log.LogLevel level : Log.LogLevel.values()) {
if (name.equals(level.name())) {
return level;
@@ -216,14 +210,32 @@ public abstract class AndroidLogFilterModel extends LogFilterModel {
return null;
}
public abstract String getSelectedLogLevelName();
@Nullable
private LogFilter getSelectedLogLevelFilter() {
final String filterName = getSelectedLogLevelName();
if (filterName != null) {
for (AndroidLogFilter logFilter : myLogFilters) {
if (filterName.equals(logFilter.myLogLevel.name())) {
return logFilter;
}
}
}
return null;
}
public boolean isFilterSelected(LogFilter filter) {
return mySelectedLogFilter == filter;
return filter == getSelectedLogLevelFilter();
}
public void selectFilter(LogFilter filter) {
if (filter != mySelectedLogFilter && filter instanceof AndroidLogFilter) {
mySelectedLogFilter = filter;
saveLogLevel(((AndroidLogFilter)filter).myLogLevel);
if (!(filter instanceof AndroidLogFilter)) {
return;
}
String newFilterName = ((AndroidLogFilter)filter).myLogLevel.name();
if (!Comparing.equal(newFilterName, getSelectedLogLevelName())) {
saveLogLevel(newFilterName);
fireFilterChange(filter);
}
}
@@ -62,7 +62,7 @@ public class AndroidLogcatToolWindowFactory implements ToolWindowFactory {
toolWindow.setToHideOnEmptyContent(true);
toolWindow.setTitle(TOOL_WINDOW_ID);
final AndroidLogcatToolWindowView view = new AndroidLogcatToolWindowView(project) {
final AndroidLogcatToolWindowView view = new AndroidLogcatToolWindowView(project, null, false) {
@Override
protected boolean isActive() {
ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(TOOL_WINDOW_ID);
@@ -25,7 +25,7 @@
<properties/>
<border type="none"/>
<children>
<scrollpane id="5ef02" class="com.intellij.ui.components.JBScrollPane">
<scrollpane id="5ef02" class="com.intellij.ui.components.JBScrollPane" binding="myFiltersListScrollPane">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
@@ -73,7 +73,7 @@
</children>
</grid>
<grid id="22eb0" binding="myRightPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="1">
<margin top="3" left="0" bottom="3" right="3"/>
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<splitpane position="right"/>
</constraints>
@@ -93,8 +93,8 @@
<border type="none"/>
<children/>
</grid>
<grid id="df093" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="5" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<grid id="df093" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="5" vgap="-1">
<margin top="3" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -122,14 +122,6 @@
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="61fcc" class="javax.swing.JButton" binding="myClearLogButton">
<constraints>
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/AndroidBundle" key="android.logcat.clear.log.button.title"/>
</properties>
</component>
<component id="f8aa6" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
@@ -36,8 +36,10 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.IconUtil;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidPlatform;
@@ -71,13 +73,14 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
private JComboBox myDeviceCombo;
private JPanel myConsoleWrapper;
private final Splitter mySplitter;
private JButton myClearLogButton;
private JPanel mySearchComponentWrapper;
private JPanel myFiltersToolbarPanel;
private JBList myFiltersList;
private JPanel myLeftPanel;
private JPanel myRightPanel;
private JPanel myTopPanel;
private JBScrollPane myFiltersListScrollPane;
private volatile IDevice myDevice;
private final Object myLock = new Object();
@@ -86,6 +89,8 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
private volatile Reader myCurrentReader;
private volatile Writer myCurrentWriter;
private final IDevice myPreselectedDevice;
private final AndroidDebugBridge.IDeviceChangeListener myDeviceChangeListener = new AndroidDebugBridge.IDeviceChangeListener() {
public void deviceConnected(IDevice device) {
updateInUIThread();
@@ -139,8 +144,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
@SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
public AndroidLogcatToolWindowView(final Project project) {
public AndroidLogcatToolWindowView(final Project project, @Nullable IDevice preselectedDevice, boolean addBorderToScrollPane) {
myProject = project;
myPreselectedDevice = preselectedDevice;
Disposer.register(myProject, this);
mySplitter = new Splitter();
@@ -148,26 +154,36 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
mySplitter.setSecondComponent(myRightPanel);
mySplitter.setProportion(0.2f);
myFiltersList.setBorder(BorderFactory.createEmptyBorder());
if (addBorderToScrollPane) {
myFiltersListScrollPane.setViewportBorder(IdeBorderFactory.createBorder());
}
else {
myFiltersList.setBorder(BorderFactory.createEmptyBorder());
}
myDeviceCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateLogConsole();
}
});
myDeviceCombo.setRenderer(new ListCellRendererWrapper() {
@Override
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value == null) {
setText("<html><font color='red'>[none]</font></html>");
if (preselectedDevice == null) {
myDeviceCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateLogConsole();
}
else if (value instanceof IDevice) {
setText(((IDevice)value).getSerialNumber());
});
myDeviceCombo.setRenderer(new ListCellRendererWrapper() {
@Override
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value == null) {
setText("<html><font color='red'>[none]</font></html>");
}
else if (value instanceof IDevice) {
setText(((IDevice)value).getSerialNumber());
}
}
}
});
});
}
else {
myTopPanel.setVisible(false);
}
final AndroidLogFilterModel logFilterModel =
new AndroidLogFilterModel(AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL) {
new AndroidLogFilterModel() {
private ConfiguredFilter myConfiguredFilter;
@Override
@@ -176,8 +192,13 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
@Override
protected void saveLogLevel(Log.LogLevel logLevel) {
AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL = logLevel.name();
protected void saveLogLevel(String logLevelName) {
AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL = logLevelName;
}
@Override
public String getSelectedLogLevelName() {
return AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_LOG_LEVEL;
}
@Override
@@ -215,7 +236,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
}
});
mySearchComponentWrapper.add(myLogConsole.getSearchComponent());
if (preselectedDevice == null) {
mySearchComponentWrapper.add(createSearchComponent(project));
}
JComponent consoleComponent = myLogConsole.getComponent();
final DefaultActionGroup group1 = new DefaultActionGroup();
@@ -233,7 +256,6 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group2, true).getComponent();
myFiltersToolbarPanel.add(tbComp2, BorderLayout.CENTER);
final String savedConfiguredFilterName = AndroidLogcatFiltersPreferences.getInstance(project).TOOL_WINDOW_CONFIGURED_FILTER;
myFiltersList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
@@ -242,7 +264,10 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
final String filterName = (String)myFiltersList.getSelectedValue();
final ConfiguredFilter filter = filterName != null ? compileConfiguredFilter(filterName) : null;
if (filterName == null) {
return;
}
final ConfiguredFilter filter = compileConfiguredFilter(filterName);
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, LogConsoleBase.APPLYING_FILTER_TITLE) {
@Override
@@ -255,7 +280,22 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
myConsoleWrapper.add(consoleComponent, BorderLayout.CENTER);
Disposer.register(this, myLogConsole);
myClearLogButton.addActionListener(new ActionListener() {
AndroidDebugBridge.addDeviceChangeListener(myDeviceChangeListener);
updateDevices();
updateLogConsole();
updateConfiguredFilters(AndroidLogcatFiltersPreferences.getInstance(myProject).TOOL_WINDOW_CONFIGURED_FILTER);
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
myFiltersList.setSelectedIndex(0);
}
}
@NotNull
public JPanel createSearchComponent(final Project project) {
final JPanel searchComponent = new JPanel(new BorderLayout());
final JButton clearLogButton = new JButton(AndroidBundle.message("android.logcat.clear.log.button.title"));
clearLogButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
IDevice device = getSelectedDevice();
if (device != null) {
@@ -264,17 +304,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
}
});
AndroidDebugBridge.addDeviceChangeListener(myDeviceChangeListener);
updateDevices();
updateLogConsole();
updateConfiguredFilters();
myFiltersList.setSelectedValue(savedConfiguredFilterName, true);
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
myFiltersList.setSelectedIndex(0);
}
searchComponent.add(myLogConsole.getSearchComponent(), BorderLayout.CENTER);
searchComponent.add(clearLogButton, BorderLayout.EAST);
return searchComponent;
}
protected abstract boolean isActive();
@@ -325,8 +357,14 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
}
public void activate() {
updateDevices();
updateLogConsole();
if (isActive()) {
updateDevices();
updateLogConsole();
updateConfiguredFilters(AndroidLogcatFiltersPreferences.getInstance(myProject).TOOL_WINDOW_CONFIGURED_FILTER);
if (myFiltersList.getSelectedValue() == null && myFiltersList.getItemsCount() > 0) {
myFiltersList.setSelectedIndex(0);
}
}
if (myLogConsole != null) {
myLogConsole.activate();
}
@@ -371,7 +409,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
@Nullable
public IDevice getSelectedDevice() {
return (IDevice)myDeviceCombo.getSelectedItem();
return myPreselectedDevice != null ? myPreselectedDevice : (IDevice)myDeviceCombo.getSelectedItem();
}
@Nullable
@@ -386,8 +424,10 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
return null;
}
private void updateConfiguredFilters() {
final String selectedFilterName = (String)myFiltersList.getSelectedValue();
private void updateConfiguredFilters(String defaultSelection) {
final String selectedFilterName = defaultSelection != null
? defaultSelection
: (String)myFiltersList.getSelectedValue();
final AndroidConfiguredLogFilters filters = AndroidConfiguredLogFilters.getInstance(myProject);
final List<AndroidConfiguredLogFilters.MyFilterEntry> entries = filters.getFilterEntries();
@@ -425,7 +465,9 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
if (devices.length > 0 && temp == null) {
temp = devices[0];
}
myDeviceCombo.setSelectedItem(temp);
if (temp != null) {
myDeviceCombo.setSelectedItem(temp);
}
}
}
else {
@@ -502,7 +544,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
entries.add(newEntry);
configuredLogFilters.setFilterEntries(entries);
updateConfiguredFilters();
updateConfiguredFilters(null);
myFiltersList.setSelectedValue(newEntry.getName(), true);
}
}
@@ -534,7 +576,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
entries.remove(filterEntry);
configuredLogFilters.setFilterEntries(entries);
updateConfiguredFilters();
updateConfiguredFilters(null);
final int index = selectedIndex < myFiltersList.getItemsCount()
? selectedIndex
: myFiltersList.getItemsCount() - 1;
@@ -567,7 +609,7 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
if (dialog.isOK()) {
final String newName = filterEntry.getName();
updateConfiguredFilters();
updateConfiguredFilters(null);
myFiltersList.setSelectedValue(newName, true);
}
}
@@ -17,6 +17,7 @@ package org.jetbrains.android.run;
import com.android.ddmlib.IDevice;
import com.intellij.debugger.engine.RemoteDebugProcessHandler;
import com.intellij.debugger.ui.DebuggerContentInfo;
import com.intellij.debugger.ui.DebuggerPanelsManager;
import com.intellij.debugger.ui.DebuggerSessionTab;
import com.intellij.execution.*;
@@ -28,21 +29,32 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.DefaultProgramRunner;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunContentManager;
import com.intellij.execution.ui.*;
import com.intellij.execution.ui.layout.PlaceInGrid;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiClass;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManagerAdapter;
import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.xdebugger.XDebuggerBundle;
import icons.AndroidIcons;
import org.jetbrains.android.dom.manifest.Instrumentation;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.logcat.AndroidLogcatToolWindowView;
import org.jetbrains.android.run.testing.AndroidTestRunConfiguration;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import static com.intellij.execution.process.ProcessOutputTypes.STDERR;
/**
@@ -55,6 +67,8 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
private static final Object myReaderLock = new Object();
private static final Object myDebugLock = new Object();
@NonNls private static final String ANDROID_DEBUG_SELECTED_TAB_PROPERTY = "ANDROID_DEBUG_SELECTED_TAB";
public static final String ANDROID_LOGCAT_CONTENT_ID = "Android Logcat";
private static void tryToCloseOldSessions(final Executor executor, Project project) {
final ExecutionManager manager = ExecutionManager.getInstance(project);
@@ -133,17 +147,20 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
private final RunnerSettings myRunnerSettings;
private final ConfigurationPerRunnerSettings myConfigurationSettings;
private final AndroidRunningState myState;
private final IDevice myDevice;
public AndroidDebugState(Project project,
RemoteConnection connection,
RunnerSettings runnerSettings,
ConfigurationPerRunnerSettings configurationSettings,
AndroidRunningState state) {
AndroidRunningState state,
IDevice device) {
myProject = project;
myConnection = connection;
myRunnerSettings = runnerSettings;
myConfigurationSettings = configurationSettings;
myState = state;
myDevice = device;
}
public RunnerSettings getRunnerSettings() {
@@ -157,7 +174,9 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
public ExecutionResult execute(final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException {
RemoteDebugProcessHandler process = new RemoteDebugProcessHandler(myProject);
myState.setProcessHandler(process);
ConsoleView console = myState.attachConsole();
final ConsoleView c = myState.getConfiguration().attachConsole(myState, executor);
final boolean resetSelectedTab = myState.getConfiguration() instanceof AndroidRunConfiguration;
final MyLogcatExecutionConsole console = new MyLogcatExecutionConsole(myProject, myDevice, process, c, resetSelectedTab);
return new DefaultExecutionResult(console, process);
}
@@ -175,6 +194,107 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
return DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) && profile instanceof AndroidRunConfigurationBase;
}
private static class MyLogcatExecutionConsole implements ExecutionConsoleEx {
private final Project myProject;
private final AndroidLogcatToolWindowView myToolWindowView;
private final ConsoleView myConsoleView;
private final boolean myResetSelectedTab;
private MyLogcatExecutionConsole(Project project,
IDevice device,
RemoteDebugProcessHandler process,
ConsoleView consoleView,
boolean resetSelectedTab) {
myProject = project;
myConsoleView = consoleView;
myResetSelectedTab = resetSelectedTab;
myToolWindowView = new AndroidLogcatToolWindowView(project, device, true) {
@Override
protected boolean isActive() {
final DebuggerSessionTab sessionTab = DebuggerPanelsManager.getInstance(myProject).getSessionTab();
if (sessionTab == null) {
return false;
}
final Content content = sessionTab.getUi().findContent(ANDROID_LOGCAT_CONTENT_ID);
return content != null && content.isSelected();
}
};
Disposer.register(this, myToolWindowView);
myToolWindowView.getLogConsole().attachStopLogConsoleTrackingListener(process);
}
@Override
public void buildUi(final RunnerLayoutUi layoutUi) {
final Content consoleContent = layoutUi.createContent(DebuggerContentInfo.CONSOLE_CONTENT, getComponent(),
XDebuggerBundle.message("debugger.session.tab.console.content.name"),
AllIcons.Debugger.Console, getPreferredFocusableComponent());
consoleContent.setCloseable(false);
layoutUi.addContent(consoleContent, 1, PlaceInGrid.bottom, false);
// todo: provide other icon
final Content logcatContent = layoutUi.createContent(ANDROID_LOGCAT_CONTENT_ID, myToolWindowView.getContentPanel(), "Logcat",
AndroidIcons.Android, getPreferredFocusableComponent());
logcatContent.setCloseable(false);
logcatContent.setSearchComponent(myToolWindowView.createSearchComponent(myProject));
layoutUi.addContent(logcatContent, 2, PlaceInGrid.bottom, false);
if (myResetSelectedTab) {
final String tabName = PropertiesComponent.getInstance().getValue(ANDROID_DEBUG_SELECTED_TAB_PROPERTY);
Content selectedContent = logcatContent;
if (tabName != null) {
for (Content content : layoutUi.getContents()) {
if (tabName.equals(content.getDisplayName())) {
selectedContent = content;
}
}
}
layoutUi.getContentManager().setSelectedContent(selectedContent);
}
layoutUi.addListener(new ContentManagerAdapter() {
public void selectionChanged(final ContentManagerEvent event) {
if (myResetSelectedTab) {
final Content content = event.getContent();
if (content.isSelected()) {
PropertiesComponent.getInstance().setValue(ANDROID_DEBUG_SELECTED_TAB_PROPERTY, content.getDisplayName());
}
}
myToolWindowView.activate();
}
}, myToolWindowView);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myToolWindowView.activate();
}
});
}
@Nullable
@Override
public String getExecutionConsoleId() {
return "ANDROID_LOGCAT";
}
@Override
public JComponent getComponent() {
return myConsoleView.getComponent();
}
@Override
public JComponent getPreferredFocusableComponent() {
return myConsoleView.getPreferredFocusableComponent();
}
@Override
public void dispose() {
}
}
private class MyDebugLauncher implements DebugLauncher {
private final Project myProject;
private final Executor myExecutor;
@@ -203,7 +323,7 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
final DebuggerPanelsManager manager = DebuggerPanelsManager.getInstance(myProject);
RemoteState st =
new AndroidDebugState(myProject, new RemoteConnection(true, "localhost", debugPort, false), myEnvironment.getRunnerSettings(),
myEnvironment.getConfigurationSettings(), myRunningState);
myEnvironment.getConfigurationSettings(), myRunningState, device);
RunContentDescriptor debugDescriptor = null;
final ProcessHandler processHandler = myRunningState.getProcessHandler();
try {
@@ -227,9 +347,26 @@ public class AndroidDebugRunner extends DefaultProgramRunner {
myRunningState.getProcessHandler().putUserData(ANDROID_PROCESS_HANDLER, debugDescriptor);
DebuggerSessionTab sessionTab = manager.getSessionTab();
final DebuggerSessionTab sessionTab = manager.getSessionTab();
assert sessionTab != null;
sessionTab.setEnvironment(myEnvironment);
/*final String contentId = "Android Logcat";
final AndroidLogcatTabComponent component = new AndroidLogcatTabComponent(myProject, device) {
@Override
public boolean isActivte() {
final Content content = sessionTab.getUi().findContent(contentId);
return content != null && content.isSelected();
}
};
sessionTab.getUi().addListener(new ContentManagerAdapter() {
public void selectionChanged(final ContentManagerEvent event) {
component.activate();
}
}, component);
component.getToolWindowView().getLogConsole().attachStopLogConsoleTrackingListener(newProcessHandler);
sessionTab.addAdditionalTabComponent(component, contentId, AllIcons.Debugger.Console);*/
RunProfile profile = myEnvironment.getRunProfile();
assert profile instanceof AndroidRunConfigurationBase;
RunContentManager runContentManager = ExecutionManager.getInstance(myProject).getContentManager();
@@ -17,11 +17,9 @@
package org.jetbrains.android.run;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Log;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
import com.intellij.CommonBundle;
import com.intellij.diagnostic.logging.LogConsole;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*;
@@ -50,8 +48,6 @@ import org.jdom.Element;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidFacetConfiguration;
import org.jetbrains.android.logcat.AndroidLogFilterModel;
import org.jetbrains.android.logcat.AndroidLogcatFiltersPreferences;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
@@ -238,14 +234,7 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
AndroidApplicationLauncher applicationLauncher = getApplicationLauncher(facet);
if (applicationLauncher != null) {
return new AndroidRunningState(env, facet, targetChooser, computeCommandLine(), aPackage, applicationLauncher,
depModule2PackageName, supportMultipleDevices(), CLEAR_LOGCAT) {
@NotNull
@Override
protected ConsoleView attachConsole() throws ExecutionException {
return AndroidRunConfigurationBase.this.attachConsole(this, executor);
}
};
depModule2PackageName, supportMultipleDevices(), CLEAR_LOGCAT, this);
}
return null;
}
@@ -298,27 +287,6 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
protected abstract boolean supportMultipleDevices();
@Override
public void customizeLogConsole(LogConsole console) {
final Project project = getProject();
console.setFilterModel(new AndroidLogFilterModel(AndroidLogcatFiltersPreferences.getInstance(project).TAB_LOG_LEVEL) {
@Override
protected void setCustomFilter(String filter) {
AndroidLogcatFiltersPreferences.getInstance(project).TAB_CUSTOM_FILTER = filter;
}
@Override
protected void saveLogLevel(Log.LogLevel logLevel) {
AndroidLogcatFiltersPreferences.getInstance(project).TAB_LOG_LEVEL = logLevel.name();
}
@Override
public String getCustomFilter() {
return AndroidLogcatFiltersPreferences.getInstance(project).TAB_CUSTOM_FILTER;
}
});
}
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
readModule(element);
@@ -84,7 +84,7 @@ import static com.intellij.execution.process.ProcessOutputTypes.STDOUT;
/**
* @author coyote
*/
public abstract class AndroidRunningState implements RunProfileState, AndroidDebugBridge.IClientChangeListener {
public class AndroidRunningState implements RunProfileState, AndroidDebugBridge.IClientChangeListener {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.run.AndroidRunningState");
@NonNls private static final String ANDROID_TARGET_DEVICES_PROPERTY = "AndroidTargetDevices";
@@ -105,6 +105,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
private final String myCommandLine;
private final AndroidApplicationLauncher myApplicationLauncher;
private final Map<AndroidFacet, String> myAdditionalFacet2PackageName;
private final AndroidRunConfigurationBase myConfiguration;
private final Object myDebugLock = new Object();
@@ -173,7 +174,7 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
}
}
else {
console = attachConsole();
console = myConfiguration.attachConsole(this, executor);
}
myConsole = console;
@@ -211,7 +212,9 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
}
@NotNull
protected abstract ConsoleView attachConsole() throws ExecutionException;
public AndroidRunConfigurationBase getConfiguration() {
return myConfiguration;
}
@Nullable
public RunnerSettings getRunnerSettings() {
@@ -287,10 +290,12 @@ public abstract class AndroidRunningState implements RunProfileState, AndroidDeb
AndroidApplicationLauncher applicationLauncher,
Map<AndroidFacet, String> additionalFacet2PackageName,
boolean supportMultipleDevices,
boolean clearLogcatBeforeStart) throws ExecutionException {
boolean clearLogcatBeforeStart,
@NotNull AndroidRunConfigurationBase configuration) throws ExecutionException {
myFacet = facet;
myCommandLine = commandLine;
myConfiguration = configuration;
myTargetChooser = targetChooser;
mySupportMultipleDevices = supportMultipleDevices;