/*
* Copyright (C) 2009 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.InvalidTypeException;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.jfree.chart.labels.CustomXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.SimpleTimePeriod;
import org.jfree.data.time.TimePeriodValues;
import org.jfree.data.time.TimePeriodValuesCollection;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
public class DisplaySyncPerf extends SyncCommon {
CustomXYToolTipGenerator mTooltipGenerator;
List mTooltips[];
// The series number for each graphed item.
// sync authorities are 0-3
private static final int DB_QUERY = 4;
private static final int DB_WRITE = 5;
private static final int HTTP_NETWORK = 6;
private static final int HTTP_PROCESSING = 7;
private static final int NUM_SERIES = (HTTP_PROCESSING + 1);
private static final String SERIES_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
"DB Query", "DB Write", "HTTP Response", "HTTP Processing",};
private static final Color SERIES_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
Color.ORANGE, Color.RED, Color.CYAN, Color.PINK, Color.DARK_GRAY};
private static final double SERIES_YCOORD[] = {0, 0, 0, 0, 1, 1, 2, 2};
// Values from data/etc/event-log-tags
private static final int EVENT_DB_OPERATION = 52000;
private static final int EVENT_HTTP_STATS = 52001;
// op types for EVENT_DB_OPERATION
final int EVENT_DB_QUERY = 0;
final int EVENT_DB_WRITE = 1;
// Information to graph for each authority
private TimePeriodValues mDatasets[];
/**
* TimePeriodValuesCollection that supports Y intervals. This allows the
* creation of "floating" bars, rather than bars rooted to the axis.
*/
class YIntervalTimePeriodValuesCollection extends TimePeriodValuesCollection {
/** default serial UID */
private static final long serialVersionUID = 1L;
private double yheight;
/**
* Constructs a collection of bars with a fixed Y height.
*
* @param yheight The height of the bars.
*/
YIntervalTimePeriodValuesCollection(double yheight) {
this.yheight = yheight;
}
/**
* Returns ending Y value that is a fixed amount greater than the starting value.
*
* @param series the series (zero-based index).
* @param item the item (zero-based index).
* @return The ending Y value for the specified series and item.
*/
@Override
public Number getEndY(int series, int item) {
return getY(series, item).doubleValue() + yheight;
}
}
/**
* Constructs a graph of network and database stats.
*
* @param name The name of this graph in the graph list.
*/
public DisplaySyncPerf(String name) {
super(name);
}
/**
* 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
public Control createComposite(final Composite parent, EventLogParser logParser,
final ILogColumnListener listener) {
Control composite = createCompositeChart(parent, logParser, "Sync Performance");
resetUI();
return composite;
}
/**
* Resets the display.
*/
@Override
void resetUI() {
super.resetUI();
XYPlot xyPlot = mChart.getXYPlot();
xyPlot.getRangeAxis().setVisible(false);
mTooltipGenerator = new CustomXYToolTipGenerator();
mTooltips = new List[NUM_SERIES];
XYBarRenderer br = new XYBarRenderer();
br.setUseYInterval(true);
mDatasets = new TimePeriodValues[NUM_SERIES];
TimePeriodValuesCollection tpvc = new YIntervalTimePeriodValuesCollection(1);
xyPlot.setDataset(tpvc);
xyPlot.setRenderer(br);
for (int i = 0; i < NUM_SERIES; i++) {
br.setSeriesPaint(i, SERIES_COLORS[i]);
mDatasets[i] = new TimePeriodValues(SERIES_NAMES[i]);
tpvc.addSeries(mDatasets[i]);
mTooltips[i] = new ArrayList<String>();
mTooltipGenerator.addToolTipSeries(mTooltips[i]);
br.setSeriesToolTipGenerator(i, mTooltipGenerator);
}
}
/**
* Updates the display with a new event.
*
* @param event The event
* @param logParser The parser providing the event.
*/
@Override
void newEvent(EventContainer event, EventLogParser logParser) {
super.newEvent(event, logParser); // Handle sync operation
try {
if (event.mTag == EVENT_DB_OPERATION) {
// 52000 db_operation (name|3),(op_type|1|5),(time|2|3)
String tip = event.getValueAsString(0);
long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
int opType = Integer.parseInt(event.getValueAsString(1));
long duration = Long.parseLong(event.getValueAsString(2));
if (opType == EVENT_DB_QUERY) {
mDatasets[DB_QUERY].add(new SimpleTimePeriod(endTime - duration, endTime),
SERIES_YCOORD[DB_QUERY]);
mTooltips[DB_QUERY].add(tip);
} else if (opType == EVENT_DB_WRITE) {
mDatasets[DB_WRITE].add(new SimpleTimePeriod(endTime - duration, endTime),
SERIES_YCOORD[DB_WRITE]);
mTooltips[DB_WRITE].add(tip);
}
} else if (event.mTag == EVENT_HTTP_STATS) {
// 52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
String tip = event.getValueAsString(0) + ", tx:" + event.getValueAsString(3) +
", rx: " + event.getValueAsString(4);
long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
long netEndTime = endTime - Long.parseLong(event.getValueAsString(2));
long netStartTime = netEndTime - Long.parseLong(event.getValueAsString(1));
mDatasets[HTTP_NETWORK].add(new SimpleTimePeriod(netStartTime, netEndTime),
SERIES_YCOORD[HTTP_NETWORK]);
mDatasets[HTTP_PROCESSING].add(new SimpleTimePeriod(netEndTime, endTime),
SERIES_YCOORD[HTTP_PROCESSING]);
mTooltips[HTTP_NETWORK].add(tip);
mTooltips[HTTP_PROCESSING].add(tip);
}
} catch (InvalidTypeException e) {
}
}
/**
* Callback from super.newEvent to process a sync event.
*
* @param event The sync event
* @param startTime Start time (ms) of events
* @param stopTime Stop time (ms) of events
* @param details Details associated with the event.
* @param newEvent True if this event is a new sync event. False if this event
* @param syncSource
*/
@Override
void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
String details, boolean newEvent, int syncSource) {
if (newEvent) {
mDatasets[auth].add(new SimpleTimePeriod(startTime, stopTime), SERIES_YCOORD[auth]);
}
}
/**
* Gets display type
*
* @return display type as an integer
*/
@Override
int getDisplayType() {
return DISPLAY_TYPE_SYNC_PERF;
}
}