blob: 26296f31c9053b186a8e318e4972feab61de2bdf [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ddmuilib.log.event;
import com.android.ddmlib.log.EventContainer;
import com.android.ddmlib.log.EventLogParser;
import com.android.ddmlib.log.EventValueDescription;
import com.android.ddmlib.log.InvalidTypeException;
import com.android.ddmuilib.DdmUiPreferences;
import com.android.ddmuilib.TableHelper;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import java.util.ArrayList;
import java.util.Calendar;
public class DisplayLog extends EventDisplay {
public DisplayLog(String name) {
super(name);
}
private final static String PREFS_COL_DATE = "EventLogPanel.log.Col1"; //$NON-NLS-1$
private final static String PREFS_COL_PID = "EventLogPanel.log.Col2"; //$NON-NLS-1$
private final static String PREFS_COL_EVENTTAG = "EventLogPanel.log.Col3"; //$NON-NLS-1$
private final static String PREFS_COL_VALUENAME = "EventLogPanel.log.Col4"; //$NON-NLS-1$
private final static String PREFS_COL_VALUE = "EventLogPanel.log.Col5"; //$NON-NLS-1$
private final static String PREFS_COL_TYPE = "EventLogPanel.log.Col6"; //$NON-NLS-1$
/**
* Resets the display.
*/
@Override
void resetUI() {
mLogTable.removeAll();
}
/**
* Adds event to the display.
*/
@Override
void newEvent(EventContainer event, EventLogParser logParser) {
addToLog(event, logParser);
}
/**
* Creates the UI for the event display.
*
* @param parent the parent composite.
* @param logParser the current log parser.
* @return the created control (which may have children).
*/
@Override
Control createComposite(Composite parent, EventLogParser logParser, ILogColumnListener listener) {
return createLogUI(parent, listener);
}
/**
* Adds an {@link EventContainer} to the log.
*
* @param event the event.
* @param logParser the log parser.
*/
private void addToLog(EventContainer event, EventLogParser logParser) {
ScrollBar bar = mLogTable.getVerticalBar();
boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
// get the date.
Calendar c = Calendar.getInstance();
long msec = (long) event.sec * 1000L;
c.setTimeInMillis(msec);
// convert the time into a string
String date = String.format("%1$tF %1$tT", c);
String eventName = logParser.getTagMap().get(event.mTag);
String pidName = Integer.toString(event.pid);
// get the value description
EventValueDescription[] valueDescription = logParser.getEventInfoMap().get(event.mTag);
if (valueDescription != null) {
for (int i = 0; i < valueDescription.length; i++) {
EventValueDescription description = valueDescription[i];
try {
String value = event.getValueAsString(i);
logValue(date, pidName, eventName, description.getName(), value,
description.getEventValueType(), description.getValueType());
} catch (InvalidTypeException e) {
logValue(date, pidName, eventName, description.getName(), e.getMessage(),
description.getEventValueType(), description.getValueType());
}
}
// scroll if needed, by showing the last item
if (scroll) {
int itemCount = mLogTable.getItemCount();
if (itemCount > 0) {
mLogTable.showItem(mLogTable.getItem(itemCount - 1));
}
}
}
}
/**
* Adds an {@link EventContainer} to the log. Only add the values/occurrences defined by
* the list of descriptors. If an event is configured to be displayed by value and occurrence,
* only the values are displayed (as they mark an event occurrence anyway).
* <p/>This method is only called when at least one of the descriptor list is non empty.
*
* @param event
* @param logParser
* @param valueDescriptors
* @param occurrenceDescriptors
*/
protected void addToLog(EventContainer event, EventLogParser logParser,
ArrayList<ValueDisplayDescriptor> valueDescriptors,
ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
ScrollBar bar = mLogTable.getVerticalBar();
boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
// get the date.
Calendar c = Calendar.getInstance();
long msec = (long) event.sec * 1000L;
c.setTimeInMillis(msec);
// convert the time into a string
String date = String.format("%1$tF %1$tT", c);
String eventName = logParser.getTagMap().get(event.mTag);
String pidName = Integer.toString(event.pid);
if (valueDescriptors.size() > 0) {
for (ValueDisplayDescriptor descriptor : valueDescriptors) {
logDescriptor(event, descriptor, date, pidName, eventName, logParser);
}
} else {
// we display the event. Since the StringBuilder contains the header (date, event name,
// pid) at this point, there isn't anything else to display.
}
// scroll if needed, by showing the last item
if (scroll) {
int itemCount = mLogTable.getItemCount();
if (itemCount > 0) {
mLogTable.showItem(mLogTable.getItem(itemCount - 1));
}
}
}
/**
* Logs a value in the ui.
*
* @param date
* @param pid
* @param event
* @param valueName
* @param value
* @param eventValueType
* @param valueType
*/
private void logValue(String date, String pid, String event, String valueName,
String value, EventContainer.EventValueType eventValueType, EventValueDescription.ValueType valueType) {
TableItem item = new TableItem(mLogTable, SWT.NONE);
item.setText(0, date);
item.setText(1, pid);
item.setText(2, event);
item.setText(3, valueName);
item.setText(4, value);
String type;
if (valueType != EventValueDescription.ValueType.NOT_APPLICABLE) {
type = String.format("%1$s, %2$s", eventValueType.toString(), valueType.toString());
} else {
type = eventValueType.toString();
}
item.setText(5, type);
}
/**
* Logs a value from an {@link EventContainer} as defined by the {@link ValueDisplayDescriptor}.
*
* @param event the EventContainer
* @param descriptor the ValueDisplayDescriptor defining which value to display.
* @param date the date of the event in a string.
* @param pidName
* @param eventName
* @param logParser
*/
private void logDescriptor(EventContainer event, ValueDisplayDescriptor descriptor,
String date, String pidName, String eventName, EventLogParser logParser) {
String value;
try {
value = event.getValueAsString(descriptor.valueIndex);
} catch (InvalidTypeException e) {
value = e.getMessage();
}
EventValueDescription[] values = logParser.getEventInfoMap().get(event.mTag);
EventValueDescription valueDescription = values[descriptor.valueIndex];
logValue(date, pidName, eventName, descriptor.valueName, value,
valueDescription.getEventValueType(), valueDescription.getValueType());
}
/**
* Creates the UI for a log display.
*
* @param parent the parent {@link Composite}
* @param listener the {@link ILogColumnListener} to notify on column resize events.
* @return the top Composite of the UI.
*/
private Control createLogUI(Composite parent, final ILogColumnListener listener) {
Composite mainComp = new Composite(parent, SWT.NONE);
GridLayout gl;
mainComp.setLayout(gl = new GridLayout(1, false));
gl.marginHeight = gl.marginWidth = 0;
mainComp.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
mLogTable = null;
}
});
Label l = new Label(mainComp, SWT.CENTER);
l.setText(mName);
l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mLogTable = new Table(mainComp, SWT.MULTI | SWT.FULL_SELECTION | SWT.V_SCROLL |
SWT.BORDER);
mLogTable.setLayoutData(new GridData(GridData.FILL_BOTH));
IPreferenceStore store = DdmUiPreferences.getStore();
TableColumn col = TableHelper.createTableColumn(
mLogTable, "Time",
SWT.LEFT, "0000-00-00 00:00:00", PREFS_COL_DATE, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(0, (TableColumn) source);
}
}
});
col = TableHelper.createTableColumn(
mLogTable, "pid",
SWT.LEFT, "0000", PREFS_COL_PID, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(1, (TableColumn) source);
}
}
});
col = TableHelper.createTableColumn(
mLogTable, "Event",
SWT.LEFT, "abcdejghijklmno", PREFS_COL_EVENTTAG, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(2, (TableColumn) source);
}
}
});
col = TableHelper.createTableColumn(
mLogTable, "Name",
SWT.LEFT, "Process Name", PREFS_COL_VALUENAME, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(3, (TableColumn) source);
}
}
});
col = TableHelper.createTableColumn(
mLogTable, "Value",
SWT.LEFT, "0000000", PREFS_COL_VALUE, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(4, (TableColumn) source);
}
}
});
col = TableHelper.createTableColumn(
mLogTable, "Type",
SWT.LEFT, "long, seconds", PREFS_COL_TYPE, store); //$NON-NLS-1$
col.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
Object source = e.getSource();
if (source instanceof TableColumn) {
listener.columnResized(5, (TableColumn) source);
}
}
});
mLogTable.setHeaderVisible(true);
mLogTable.setLinesVisible(true);
return mainComp;
}
/**
* Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
* <p/>
* This does nothing if the <code>Table</code> object is <code>null</code> (because the display
* type does not use a column) or if the <code>index</code>-th column is in fact the originating
* column passed as argument.
*
* @param index the index of the column to resize
* @param sourceColumn the original column that was resize, and on which we need to sync the
* index-th column width.
*/
@Override
void resizeColumn(int index, TableColumn sourceColumn) {
if (mLogTable != null) {
TableColumn col = mLogTable.getColumn(index);
if (col != sourceColumn) {
col.setWidth(sourceColumn.getWidth());
}
}
}
/**
* Gets display type
*
* @return display type as an integer
*/
@Override
int getDisplayType() {
return DISPLAY_TYPE_LOG_ALL;
}
}