FileDocCategorySizeDatePackage
EventDisplay.javaAPI DocAndroid 1.5 API33842Wed May 06 22:41:08 BST 2009com.android.ddmuilib.log.event

EventDisplay

public abstract class EventDisplay extends Object
Represents a custom display of one or more events.

Fields Summary
private static final String
DISPLAY_DATA_STORAGE_SEPARATOR
private static final String
PID_STORAGE_SEPARATOR
private static final String
DESCRIPTOR_STORAGE_SEPARATOR
private static final String
DESCRIPTOR_DATA_STORAGE_SEPARATOR
private static final String
FILTER_VALUE_NULL
public static final int
DISPLAY_TYPE_LOG_ALL
public static final int
DISPLAY_TYPE_FILTERED_LOG
public static final int
DISPLAY_TYPE_GRAPH
public static final int
DISPLAY_TYPE_SYNC
public static final int
DISPLAY_TYPE_SYNC_HIST
public static final int
DISPLAY_TYPE_SYNC_PERF
private static final int
EVENT_CHECK_FAILED
protected static final int
EVENT_CHECK_SAME_TAG
protected static final int
EVENT_CHECK_SAME_VALUE
protected String
mName
private boolean
mPidFiltering
private ArrayList
mPidFilterList
protected final ArrayList
mValueDescriptors
private final ArrayList
mOccurrenceDescriptors
protected final HashMap
mValueDescriptorSeriesMap
This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
protected final HashMap
mOcurrenceDescriptorSeriesMap
This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
protected final HashMap
mValueTypeDataSetMap
This is a map of (ValueType, dataset)
protected org.jfree.chart.JFreeChart
mChart
protected org.jfree.data.time.TimeSeriesCollection
mOccurrenceDataSet
protected int
mDataSetCount
private org.jfree.experimental.chart.swt.ChartComposite
mChartComposite
protected long
mMaximumChartItemAge
protected long
mHistWidth
protected org.eclipse.swt.widgets.Table
mLogTable
protected int
mValueDescriptorCheck
Constructors Summary
EventDisplay(String name)


      
        mName = name;
    
Methods Summary
voidaddDescriptor(com.android.ddmuilib.log.event.EventDisplay$OccurrenceDisplayDescriptor descriptor)
Adds a descriptor. This can be a {@link OccurrenceDisplayDescriptor} or a {@link ValueDisplayDescriptor}.

param
descriptor the descriptor to be added.

        if (descriptor instanceof ValueDisplayDescriptor) {
            mValueDescriptors.add((ValueDisplayDescriptor) descriptor);
            mValueDescriptorCheck = checkDescriptors();
        } else {
            mOccurrenceDescriptors.add(descriptor);
        }
    
voidaddPidFiler(int pid)

        if (mPidFiltering == false) {
            new InvalidParameterException();
        }

        if (mPidFilterList == null) {
            mPidFilterList = new ArrayList<Integer>();
        }

        mPidFilterList.add(pid);
    
private intcheckDescriptors()
Checks all the {@link ValueDisplayDescriptor} for similarity. If all the event values are from the same tag, the method will return EVENT_CHECK_SAME_TAG. If all the event/value are the same, the method will return EVENT_CHECK_SAME_VALUE

return
flag as described above

        if (mValueDescriptors.size() < 2) {
            return EVENT_CHECK_SAME_VALUE;
        }

        int tag = -1;
        int index = -1;
        for (ValueDisplayDescriptor display : mValueDescriptors) {
            if (tag == -1) {
                tag = display.eventTag;
                index = display.valueIndex;
            } else {
                if (tag != display.eventTag) {
                    return EVENT_CHECK_FAILED;
                } else {
                    if (index != -1) {
                        if (index != display.valueIndex) {
                            index = -1;
                        }
                    }
                }
            }
        }

        if (index == -1) {
            return EVENT_CHECK_SAME_TAG;
        }

        return EVENT_CHECK_SAME_VALUE;
    
static com.android.ddmuilib.log.event.EventDisplayclone(com.android.ddmuilib.log.event.EventDisplay from)

        EventDisplay ed = eventDisplayFactory(from.getDisplayType(), from.getName());
        ed.mName = from.mName;
        ed.mPidFiltering = from.mPidFiltering;
        ed.mMaximumChartItemAge = from.mMaximumChartItemAge;
        ed.mHistWidth = from.mHistWidth;

        if (from.mPidFilterList != null) {
            ed.mPidFilterList = new ArrayList<Integer>();
            ed.mPidFilterList.addAll(from.mPidFilterList);
        }

        for (ValueDisplayDescriptor desc : from.mValueDescriptors) {
            ed.mValueDescriptors.add(new ValueDisplayDescriptor(desc));
        }
        ed.mValueDescriptorCheck = from.mValueDescriptorCheck;

        for (OccurrenceDisplayDescriptor desc : from.mOccurrenceDescriptors) {
            ed.mOccurrenceDescriptors.add(new OccurrenceDisplayDescriptor(desc));
        }
        return ed;
    
abstract org.eclipse.swt.widgets.ControlcreateComposite(org.eclipse.swt.widgets.Composite parent, com.android.ddmlib.log.EventLogParser logParser, com.android.ddmuilib.log.event.EventDisplay$ILogColumnListener listener)
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).

org.eclipse.swt.widgets.ControlcreateCompositeChart(org.eclipse.swt.widgets.Composite parent, com.android.ddmlib.log.EventLogParser logParser, java.lang.String title)

        mChart = ChartFactory.createTimeSeriesChart(
                null,
                null /* timeAxisLabel */,
                null /* valueAxisLabel */,
                null, /* dataset. set below */
                true /* legend */,
                false /* tooltips */,
                false /* urls */);

        // get the font to make a proper title. We need to convert the swt font,
        // into an awt font.
        Font f = parent.getFont();
        FontData[] fData = f.getFontData();

        // event though on Mac OS there could be more than one fontData, we'll only use
        // the first one.
        FontData firstFontData = fData[0];

        java.awt.Font awtFont = SWTUtils.toAwtFont(parent.getDisplay(),
                firstFontData, true /* ensureSameSize */);


        mChart.setTitle(new TextTitle(title, awtFont));

        final XYPlot xyPlot = mChart.getXYPlot();
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.setRangeCrosshairLockedOnData(true);
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setDomainCrosshairLockedOnData(true);

        mChart.addChangeListener(new ChartChangeListener() {
            public void chartChanged(ChartChangeEvent event) {
                ChartChangeEventType type = event.getType();
                if (type == ChartChangeEventType.GENERAL) {
                    // because the value we need (rangeCrosshair and domainCrosshair) are
                    // updated on the draw, but the notification happens before the draw,
                    // we process the click in a future runnable!
                    parent.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            processClick(xyPlot);
                        }
                    });
                }
            }
        });

        mChartComposite = new ChartComposite(parent, SWT.BORDER, mChart,
                ChartComposite.DEFAULT_WIDTH,
                ChartComposite.DEFAULT_HEIGHT,
                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
                3000, // max draw width. We don't want it to zoom, so we put a big number
                3000, // max draw height. We don't want it to zoom, so we put a big number
                true,  // off-screen buffer
                true,  // properties
                true,  // save
                true,  // print
                true,  // zoom
                true);   // tooltips

        mChartComposite.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                mValueTypeDataSetMap.clear();
                mDataSetCount = 0;
                mOccurrenceDataSet = null;
                mChart = null;
                mChartComposite = null;
                mValueDescriptorSeriesMap.clear();
                mOcurrenceDescriptorSeriesMap.clear();
            }
        });

        return mChartComposite;

    
voidendMultiEventDisplay()
Finalizes the {@link EventDisplay} after a multi event display.

        if (mLogTable != null) {
            mLogTable.setRedraw(true);
        }
    
public static com.android.ddmuilib.log.event.EventDisplayeventDisplayFactory(int type, java.lang.String name)
Creates the appropriate EventDisplay subclass.

param
type the type of display (DISPLAY_TYPE_LOG_ALL, etc)
param
name the name of the display
return
the created object


                                 
           
        switch (type) {
            case DISPLAY_TYPE_LOG_ALL:
                return new DisplayLog(name);
            case DISPLAY_TYPE_FILTERED_LOG:
                return new DisplayFilteredLog(name);
            case DISPLAY_TYPE_SYNC:
                return new DisplaySync(name);
            case DISPLAY_TYPE_SYNC_HIST:
                return new DisplaySyncHistogram(name);
            case DISPLAY_TYPE_GRAPH:
                return new DisplayGraph(name);
            case DISPLAY_TYPE_SYNC_PERF:
                return new DisplaySyncPerf(name);
            default:
                throw new InvalidParameterException("Unknown Display Type " + type); //$NON-NLS-1$
        }
    
protected booleanfilterEvent(com.android.ddmlib.log.EventContainer event, java.util.ArrayList valueDescriptors, java.util.ArrayList occurrenceDescriptors)
Filters the {@link com.android.ddmlib.log.EventContainer}, and fills two list of {@link com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor} and {@link com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor} configured to display the event.

param
event
param
valueDescriptors
param
occurrenceDescriptors
return
true if the event should be displayed.


        // test the pid first (if needed)
        if (mPidFiltering && mPidFilterList != null) {
            boolean found = false;
            for (int pid : mPidFilterList) {
                if (pid == event.pid) {
                    found = true;
                    break;
                }
            }

            if (found == false) {
                return false;
            }
        }

        // now get the list of matching descriptors
        getDescriptors(event, mValueDescriptors, valueDescriptors);
        getDescriptors(event, mOccurrenceDescriptors, occurrenceDescriptors);

        // and return whether there is at least one match in either list.
        return (valueDescriptors.size() > 0 || occurrenceDescriptors.size() > 0);
    
longgetChartTimeLimit()

        return mMaximumChartItemAge;
    
com.android.ddmuilib.log.event.EventDisplay$OccurrenceDisplayDescriptorgetDescriptor(java.lang.Class descriptorClass, int index)
Returns a descriptor by index and class (extending {@link OccurrenceDisplayDescriptor}).

param
descriptorClass the class of the descriptor to return.
param
index the index of the descriptor to return.
return
either a {@link OccurrenceDisplayDescriptor} or a {@link ValueDisplayDescriptor} or null if descriptorClass is another class.


        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
            return mOccurrenceDescriptors.get(index);
        } else if (descriptorClass == ValueDisplayDescriptor.class) {
            return mValueDescriptors.get(index);
        }

        return null;
    
private java.lang.StringgetDescriptorStorageString(java.util.ArrayList descriptorList)

        StringBuilder sb = new StringBuilder();
        boolean first = true;

        for (OccurrenceDisplayDescriptor descriptor : descriptorList) {
            if (first == false) {
                sb.append(DESCRIPTOR_STORAGE_SEPARATOR);
            } else {
                first = false;
            }
            sb.append(descriptor.getStorageString());
        }

        return sb.toString();
    
private voidgetDescriptors(com.android.ddmlib.log.EventContainer event, java.util.ArrayList fullList, java.util.ArrayList outList)
Fills a list with {@link OccurrenceDisplayDescriptor} (or a subclass of it) from another list if they are configured to display the {@link EventContainer}

param
event the event container
param
fullList the list with all the descriptors.
param
outList the list to fill.

        for (OccurrenceDisplayDescriptor descriptor : fullList) {
            try {
                // first check the event tag.
                if (descriptor.eventTag == event.mTag) {
                    // now check if we have a filter on a value
                    if (descriptor.filterValueIndex == -1 ||
                            event.testValue(descriptor.filterValueIndex, descriptor.filterValue,
                                    descriptor.filterCompareMethod)) {
                        outList.add(descriptor);
                    }
                }
            } catch (InvalidTypeException ite) {
                // if the filter for the descriptor was incorrect, we ignore the descriptor.
            } catch (ArrayIndexOutOfBoundsException aioobe) {
                // if the index was wrong (the event content may have changed since we setup the
                // display), we do nothing but log the error
                Log.e("Event Log", String.format(
                        "ArrayIndexOutOfBoundsException occured when checking %1$d-th value of event %2$d", //$NON-NLS-1$
                        descriptor.filterValueIndex, descriptor.eventTag));
            }
        }
    
abstract intgetDisplayType()
Gets display type

return
display type as an integer

longgetHistWidth()

        return mHistWidth;
    
java.lang.StringgetName()

        return mName;
    
java.util.IteratorgetOccurrenceDescriptors()
Returns an iterator to the list of {@link OccurrenceDisplayDescriptor}.

        return mOccurrenceDescriptors.iterator();
    
java.util.ArrayListgetPidFilterList()

        return mPidFilterList;
    
booleangetPidFiltering()

        return mPidFiltering;
    
private java.lang.StringgetPidStorageString()

        if (mPidFilterList != null) {
            StringBuilder sb = new StringBuilder();
            boolean first = true;
            for (Integer i : mPidFilterList) {
                if (first == false) {
                    sb.append(PID_STORAGE_SEPARATOR);
                } else {
                    first = false;
                }
                sb.append(i);
            }

            return sb.toString();
        }
        return ""; //$NON-NLS-1$
    
java.lang.StringgetStorageString()
Returns the parameters of the receiver as a single String for storage.

        StringBuilder sb = new StringBuilder();

        sb.append(mName);
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(getDisplayType());
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(Boolean.toString(mPidFiltering));
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(getPidStorageString());
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(getDescriptorStorageString(mValueDescriptors));
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(getDescriptorStorageString(mOccurrenceDescriptors));
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(mMaximumChartItemAge);
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
        sb.append(mHistWidth);
        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);

        return sb.toString();
    
org.eclipse.swt.widgets.TablegetTable()
Returns the {@link Table} object used to display events, if any.

return
a Table object or null.

        return mLogTable;
    
java.util.IteratorgetValueDescriptors()
Returns an iterator to the list of {@link ValueDisplayDescriptor}.

        return mValueDescriptors.iterator();
    
static com.android.ddmuilib.log.event.EventDisplayload(java.lang.String storageString)
Loads a new {@link EventDisplay} from a storage string. The string must have been created with {@link #getStorageString()}.

param
storageString the storage string
return
a new {@link EventDisplay} or null if the load failed.

        if (storageString.length() > 0) {
            // the storage string is separated by ':'
            String[] values = storageString.split(Pattern.quote(DISPLAY_DATA_STORAGE_SEPARATOR));

            try {
                int index = 0;

                String name = values[index++];
                int displayType = Integer.parseInt(values[index++]);
                boolean pidFiltering = Boolean.parseBoolean(values[index++]);

                EventDisplay ed = eventDisplayFactory(displayType, name);
                ed.setPidFiltering(pidFiltering);

                // because empty sections are removed by String.split(), we have to check
                // the index for those.
                if (index < values.length) {
                    ed.loadPidFilters(values[index++]);
                }

                if (index < values.length) {
                    ed.loadValueDescriptors(values[index++]);
                }

                if (index < values.length) {
                    ed.loadOccurrenceDescriptors(values[index++]);
                }

                ed.updateValueDescriptorCheck();

                if (index < values.length) {
                    ed.mMaximumChartItemAge = Long.parseLong(values[index++]);
                }

                if (index < values.length) {
                    ed.mHistWidth = Long.parseLong(values[index++]);
                }

                return ed;
            } catch (RuntimeException re) {
                // we'll return null below.
                Log.e("ddms", re);
            }
        }

        return null;
    
private voidloadOccurrenceDescriptors(java.lang.String storageString)

        if (storageString.length() == 0) {
            return;
        }

        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));

        for (String value : values) {
            OccurrenceDisplayDescriptor desc = new OccurrenceDisplayDescriptor();
            desc.loadFrom(value);
            mOccurrenceDescriptors.add(desc);
        }
    
private voidloadPidFilters(java.lang.String storageString)

        if (storageString.length() > 0) {
            String[] values = storageString.split(Pattern.quote(PID_STORAGE_SEPARATOR));

            for (String value : values) {
                if (mPidFilterList == null) {
                    mPidFilterList = new ArrayList<Integer>();
                }
                mPidFilterList.add(Integer.parseInt(value));
            }
        }
    
private voidloadValueDescriptors(java.lang.String storageString)

        if (storageString.length() == 0) {
            return;
        }

        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));

        for (String value : values) {
            ValueDisplayDescriptor desc = new ValueDisplayDescriptor();
            desc.loadFrom(value);
            mValueDescriptors.add(desc);
        }
    
abstract voidnewEvent(com.android.ddmlib.log.EventContainer event, com.android.ddmlib.log.EventLogParser logParser)
Adds event to the display.

param
event The event
param
logParser The log parser.

private voidprocessClick(org.jfree.chart.plot.XYPlot xyPlot)

        double rangeValue = xyPlot.getRangeCrosshairValue();
        if (rangeValue != 0) {
            double domainValue = xyPlot.getDomainCrosshairValue();

            Millisecond msec = new Millisecond(new Date((long) domainValue));

            // look for values in the dataset that contains data at this TimePeriod
            Set<ValueDisplayDescriptor> descKeys = mValueDescriptorSeriesMap.keySet();

            for (ValueDisplayDescriptor descKey : descKeys) {
                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descKey);

                Set<Integer> pidKeys = map.keySet();

                for (Integer pidKey : pidKeys) {
                    TimeSeries series = map.get(pidKey);

                    Number value = series.getValue(msec);
                    if (value != null) {
                        // found a match. lets check against the actual value.
                        if (value.doubleValue() == rangeValue) {

                            return;
                        }
                    }
                }
            }
        }
    
voidremoveDescriptor(java.lang.Class descriptorClass, int index)
Removes a descriptor based on its class and index.

param
descriptorClass the class of the descriptor.
param
index the index of the descriptor to be removed.

        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
            mOccurrenceDescriptors.remove(index);
        } else if (descriptorClass == ValueDisplayDescriptor.class) {
            mValueDescriptors.remove(index);
            mValueDescriptorCheck = checkDescriptors();
        }
    
voidresetChartTimeLimit()
Resets the time limit on the chart to be infinite.

        mMaximumChartItemAge = -1;
    
voidresetHistWidth()
m Resets the histogram width

        mHistWidth = 1;
    
abstract voidresetUI()
Resets the display.

voidresizeColumn(int index, org.eclipse.swt.widgets.TableColumn sourceColumn)
Resizes the index-th column of the log {@link Table} (if applicable). Subclasses can override if necessary.

This does nothing if the Table object is null (because the display type does not use a column) or if the index-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.

    
voidsetChartTimeLimit(long timeLimit)
Sets the time limit on the charts.

param
timeLimit the time limit in seconds.

        mMaximumChartItemAge = timeLimit;
    
voidsetHistWidth(long histWidth)
Sets the histogram width

param
histWidth the width in hours

        mHistWidth = histWidth;
    
voidsetName(java.lang.String name)

        mName = name;
    
protected voidsetNewLogParser(com.android.ddmlib.log.EventLogParser logParser)
Sets the current {@link EventLogParser} object. Subclasses can override if necessary.

    
voidsetPidFilterList(java.util.ArrayList pids)

        if (mPidFiltering == false) {
            new InvalidParameterException();
        }

        mPidFilterList = pids;
    
voidsetPidFiltering(boolean filterByPid)

        mPidFiltering = filterByPid;
    
voidstartMultiEventDisplay()
Prepares the {@link EventDisplay} for a multi event display.

        if (mLogTable != null) {
            mLogTable.setRedraw(false);
        }
    
voidupdateValueDescriptorCheck()
Update checks on the descriptors. Must be called whenever a descriptor is modified outside of this class.

        mValueDescriptorCheck = checkDescriptors();