Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ddmuilib.log.event;
     18 
     19 import com.android.ddmlib.log.EventContainer;
     20 import com.android.ddmlib.log.EventLogParser;
     21 import com.android.ddmlib.log.EventValueDescription;
     22 import com.android.ddmlib.log.InvalidTypeException;
     23 import com.android.ddmuilib.DdmUiPreferences;
     24 import com.android.ddmuilib.TableHelper;
     25 import org.eclipse.jface.preference.IPreferenceStore;
     26 import org.eclipse.swt.SWT;
     27 import org.eclipse.swt.events.ControlAdapter;
     28 import org.eclipse.swt.events.ControlEvent;
     29 import org.eclipse.swt.events.DisposeEvent;
     30 import org.eclipse.swt.events.DisposeListener;
     31 import org.eclipse.swt.layout.GridData;
     32 import org.eclipse.swt.layout.GridLayout;
     33 import org.eclipse.swt.widgets.Composite;
     34 import org.eclipse.swt.widgets.Control;
     35 import org.eclipse.swt.widgets.Label;
     36 import org.eclipse.swt.widgets.ScrollBar;
     37 import org.eclipse.swt.widgets.Table;
     38 import org.eclipse.swt.widgets.TableColumn;
     39 import org.eclipse.swt.widgets.TableItem;
     40 
     41 import java.util.ArrayList;
     42 import java.util.Calendar;
     43 
     44 public class DisplayLog extends EventDisplay {
     45     public DisplayLog(String name) {
     46         super(name);
     47     }
     48 
     49     private final static String PREFS_COL_DATE = "EventLogPanel.log.Col1"; //$NON-NLS-1$
     50     private final static String PREFS_COL_PID = "EventLogPanel.log.Col2"; //$NON-NLS-1$
     51     private final static String PREFS_COL_EVENTTAG = "EventLogPanel.log.Col3"; //$NON-NLS-1$
     52     private final static String PREFS_COL_VALUENAME = "EventLogPanel.log.Col4"; //$NON-NLS-1$
     53     private final static String PREFS_COL_VALUE = "EventLogPanel.log.Col5"; //$NON-NLS-1$
     54     private final static String PREFS_COL_TYPE = "EventLogPanel.log.Col6"; //$NON-NLS-1$
     55 
     56     /**
     57      * Resets the display.
     58      */
     59     @Override
     60     void resetUI() {
     61         mLogTable.removeAll();
     62     }
     63 
     64     /**
     65      * Adds event to the display.
     66      */
     67     @Override
     68     void newEvent(EventContainer event, EventLogParser logParser) {
     69         addToLog(event, logParser);
     70     }
     71 
     72     /**
     73      * Creates the UI for the event display.
     74      *
     75      * @param parent    the parent composite.
     76      * @param logParser the current log parser.
     77      * @return the created control (which may have children).
     78      */
     79     @Override
     80     Control createComposite(Composite parent, EventLogParser logParser, ILogColumnListener listener) {
     81         return createLogUI(parent, listener);
     82     }
     83 
     84     /**
     85      * Adds an {@link EventContainer} to the log.
     86      *
     87      * @param event     the event.
     88      * @param logParser the log parser.
     89      */
     90     private void addToLog(EventContainer event, EventLogParser logParser) {
     91         ScrollBar bar = mLogTable.getVerticalBar();
     92         boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
     93 
     94         // get the date.
     95         Calendar c = Calendar.getInstance();
     96         long msec = (long) event.sec * 1000L;
     97         c.setTimeInMillis(msec);
     98 
     99         // convert the time into a string
    100         String date = String.format("%1$tF %1$tT", c);
    101 
    102         String eventName = logParser.getTagMap().get(event.mTag);
    103         String pidName = Integer.toString(event.pid);
    104 
    105         // get the value description
    106         EventValueDescription[] valueDescription = logParser.getEventInfoMap().get(event.mTag);
    107         if (valueDescription != null) {
    108             for (int i = 0; i < valueDescription.length; i++) {
    109                 EventValueDescription description = valueDescription[i];
    110                 try {
    111                     String value = event.getValueAsString(i);
    112 
    113                     logValue(date, pidName, eventName, description.getName(), value,
    114                             description.getEventValueType(), description.getValueType());
    115                 } catch (InvalidTypeException e) {
    116                     logValue(date, pidName, eventName, description.getName(), e.getMessage(),
    117                             description.getEventValueType(), description.getValueType());
    118                 }
    119             }
    120 
    121             // scroll if needed, by showing the last item
    122             if (scroll) {
    123                 int itemCount = mLogTable.getItemCount();
    124                 if (itemCount > 0) {
    125                     mLogTable.showItem(mLogTable.getItem(itemCount - 1));
    126                 }
    127             }
    128         }
    129     }
    130 
    131     /**
    132      * Adds an {@link EventContainer} to the log. Only add the values/occurrences defined by
    133      * the list of descriptors. If an event is configured to be displayed by value and occurrence,
    134      * only the values are displayed (as they mark an event occurrence anyway).
    135      * <p/>This method is only called when at least one of the descriptor list is non empty.
    136      *
    137      * @param event
    138      * @param logParser
    139      * @param valueDescriptors
    140      * @param occurrenceDescriptors
    141      */
    142     protected void addToLog(EventContainer event, EventLogParser logParser,
    143             ArrayList<ValueDisplayDescriptor> valueDescriptors,
    144             ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
    145         ScrollBar bar = mLogTable.getVerticalBar();
    146         boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
    147 
    148         // get the date.
    149         Calendar c = Calendar.getInstance();
    150         long msec = (long) event.sec * 1000L;
    151         c.setTimeInMillis(msec);
    152 
    153         // convert the time into a string
    154         String date = String.format("%1$tF %1$tT", c);
    155 
    156         String eventName = logParser.getTagMap().get(event.mTag);
    157         String pidName = Integer.toString(event.pid);
    158 
    159         if (valueDescriptors.size() > 0) {
    160             for (ValueDisplayDescriptor descriptor : valueDescriptors) {
    161                 logDescriptor(event, descriptor, date, pidName, eventName, logParser);
    162             }
    163         } else {
    164             // we display the event. Since the StringBuilder contains the header (date, event name,
    165             // pid) at this point, there isn't anything else to display.
    166         }
    167 
    168         // scroll if needed, by showing the last item
    169         if (scroll) {
    170             int itemCount = mLogTable.getItemCount();
    171             if (itemCount > 0) {
    172                 mLogTable.showItem(mLogTable.getItem(itemCount - 1));
    173             }
    174         }
    175     }
    176 
    177 
    178     /**
    179      * Logs a value in the ui.
    180      *
    181      * @param date
    182      * @param pid
    183      * @param event
    184      * @param valueName
    185      * @param value
    186      * @param eventValueType
    187      * @param valueType
    188      */
    189     private void logValue(String date, String pid, String event, String valueName,
    190             String value, EventContainer.EventValueType eventValueType, EventValueDescription.ValueType valueType) {
    191 
    192         TableItem item = new TableItem(mLogTable, SWT.NONE);
    193         item.setText(0, date);
    194         item.setText(1, pid);
    195         item.setText(2, event);
    196         item.setText(3, valueName);
    197         item.setText(4, value);
    198 
    199         String type;
    200         if (valueType != EventValueDescription.ValueType.NOT_APPLICABLE) {
    201             type = String.format("%1$s, %2$s", eventValueType.toString(), valueType.toString());
    202         } else {
    203             type = eventValueType.toString();
    204         }
    205 
    206         item.setText(5, type);
    207     }
    208 
    209     /**
    210      * Logs a value from an {@link EventContainer} as defined by the {@link ValueDisplayDescriptor}.
    211      *
    212      * @param event      the EventContainer
    213      * @param descriptor the ValueDisplayDescriptor defining which value to display.
    214      * @param date       the date of the event in a string.
    215      * @param pidName
    216      * @param eventName
    217      * @param logParser
    218      */
    219     private void logDescriptor(EventContainer event, ValueDisplayDescriptor descriptor,
    220             String date, String pidName, String eventName, EventLogParser logParser) {
    221 
    222         String value;
    223         try {
    224             value = event.getValueAsString(descriptor.valueIndex);
    225         } catch (InvalidTypeException e) {
    226             value = e.getMessage();
    227         }
    228 
    229         EventValueDescription[] values = logParser.getEventInfoMap().get(event.mTag);
    230 
    231         EventValueDescription valueDescription = values[descriptor.valueIndex];
    232 
    233         logValue(date, pidName, eventName, descriptor.valueName, value,
    234                 valueDescription.getEventValueType(), valueDescription.getValueType());
    235     }
    236 
    237     /**
    238      * Creates the UI for a log display.
    239      *
    240      * @param parent   the parent {@link Composite}
    241      * @param listener the {@link ILogColumnListener} to notify on column resize events.
    242      * @return the top Composite of the UI.
    243      */
    244     private Control createLogUI(Composite parent, final ILogColumnListener listener) {
    245         Composite mainComp = new Composite(parent, SWT.NONE);
    246         GridLayout gl;
    247         mainComp.setLayout(gl = new GridLayout(1, false));
    248         gl.marginHeight = gl.marginWidth = 0;
    249         mainComp.addDisposeListener(new DisposeListener() {
    250             public void widgetDisposed(DisposeEvent e) {
    251                 mLogTable = null;
    252             }
    253         });
    254 
    255         Label l = new Label(mainComp, SWT.CENTER);
    256         l.setText(mName);
    257         l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    258 
    259         mLogTable = new Table(mainComp, SWT.MULTI | SWT.FULL_SELECTION | SWT.V_SCROLL |
    260                 SWT.BORDER);
    261         mLogTable.setLayoutData(new GridData(GridData.FILL_BOTH));
    262 
    263         IPreferenceStore store = DdmUiPreferences.getStore();
    264 
    265         TableColumn col = TableHelper.createTableColumn(
    266                 mLogTable, "Time",
    267                 SWT.LEFT, "0000-00-00 00:00:00", PREFS_COL_DATE, store); //$NON-NLS-1$
    268         col.addControlListener(new ControlAdapter() {
    269             @Override
    270             public void controlResized(ControlEvent e) {
    271                 Object source = e.getSource();
    272                 if (source instanceof TableColumn) {
    273                     listener.columnResized(0, (TableColumn) source);
    274                 }
    275             }
    276         });
    277 
    278         col = TableHelper.createTableColumn(
    279                 mLogTable, "pid",
    280                 SWT.LEFT, "0000", PREFS_COL_PID, store); //$NON-NLS-1$
    281         col.addControlListener(new ControlAdapter() {
    282             @Override
    283             public void controlResized(ControlEvent e) {
    284                 Object source = e.getSource();
    285                 if (source instanceof TableColumn) {
    286                     listener.columnResized(1, (TableColumn) source);
    287                 }
    288             }
    289         });
    290 
    291         col = TableHelper.createTableColumn(
    292                 mLogTable, "Event",
    293                 SWT.LEFT, "abcdejghijklmno", PREFS_COL_EVENTTAG, store); //$NON-NLS-1$
    294         col.addControlListener(new ControlAdapter() {
    295             @Override
    296             public void controlResized(ControlEvent e) {
    297                 Object source = e.getSource();
    298                 if (source instanceof TableColumn) {
    299                     listener.columnResized(2, (TableColumn) source);
    300                 }
    301             }
    302         });
    303 
    304         col = TableHelper.createTableColumn(
    305                 mLogTable, "Name",
    306                 SWT.LEFT, "Process Name", PREFS_COL_VALUENAME, store); //$NON-NLS-1$
    307         col.addControlListener(new ControlAdapter() {
    308             @Override
    309             public void controlResized(ControlEvent e) {
    310                 Object source = e.getSource();
    311                 if (source instanceof TableColumn) {
    312                     listener.columnResized(3, (TableColumn) source);
    313                 }
    314             }
    315         });
    316 
    317         col = TableHelper.createTableColumn(
    318                 mLogTable, "Value",
    319                 SWT.LEFT, "0000000", PREFS_COL_VALUE, store); //$NON-NLS-1$
    320         col.addControlListener(new ControlAdapter() {
    321             @Override
    322             public void controlResized(ControlEvent e) {
    323                 Object source = e.getSource();
    324                 if (source instanceof TableColumn) {
    325                     listener.columnResized(4, (TableColumn) source);
    326                 }
    327             }
    328         });
    329 
    330         col = TableHelper.createTableColumn(
    331                 mLogTable, "Type",
    332                 SWT.LEFT, "long, seconds", PREFS_COL_TYPE, store); //$NON-NLS-1$
    333         col.addControlListener(new ControlAdapter() {
    334             @Override
    335             public void controlResized(ControlEvent e) {
    336                 Object source = e.getSource();
    337                 if (source instanceof TableColumn) {
    338                     listener.columnResized(5, (TableColumn) source);
    339                 }
    340             }
    341         });
    342 
    343         mLogTable.setHeaderVisible(true);
    344         mLogTable.setLinesVisible(true);
    345 
    346         return mainComp;
    347     }
    348 
    349     /**
    350      * Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
    351      * <p/>
    352      * This does nothing if the <code>Table</code> object is <code>null</code> (because the display
    353      * type does not use a column) or if the <code>index</code>-th column is in fact the originating
    354      * column passed as argument.
    355      *
    356      * @param index        the index of the column to resize
    357      * @param sourceColumn the original column that was resize, and on which we need to sync the
    358      *                     index-th column width.
    359      */
    360     @Override
    361     void resizeColumn(int index, TableColumn sourceColumn) {
    362         if (mLogTable != null) {
    363             TableColumn col = mLogTable.getColumn(index);
    364             if (col != sourceColumn) {
    365                 col.setWidth(sourceColumn.getWidth());
    366             }
    367         }
    368     }
    369 
    370     /**
    371      * Gets display type
    372      *
    373      * @return display type as an integer
    374      */
    375     @Override
    376     int getDisplayType() {
    377         return DISPLAY_TYPE_LOG_ALL;
    378     }
    379 }
    380