| /* |
| * 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; |
| } |
| } |