Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright (C) 2009 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.InvalidTypeException;
     22 import org.eclipse.swt.widgets.Composite;
     23 import org.eclipse.swt.widgets.Control;
     24 import org.jfree.chart.labels.CustomXYToolTipGenerator;
     25 import org.jfree.chart.plot.XYPlot;
     26 import org.jfree.chart.renderer.xy.XYBarRenderer;
     27 import org.jfree.data.time.SimpleTimePeriod;
     28 import org.jfree.data.time.TimePeriodValues;
     29 import org.jfree.data.time.TimePeriodValuesCollection;
     30 
     31 import java.awt.Color;
     32 import java.util.ArrayList;
     33 import java.util.List;
     34 
     35 public class DisplaySyncPerf extends SyncCommon {
     36 
     37     CustomXYToolTipGenerator mTooltipGenerator;
     38     List mTooltips[];
     39 
     40     // The series number for each graphed item.
     41     // sync authorities are 0-3
     42     private static final int DB_QUERY = 4;
     43     private static final int DB_WRITE = 5;
     44     private static final int HTTP_NETWORK = 6;
     45     private static final int HTTP_PROCESSING = 7;
     46     private static final int NUM_SERIES = (HTTP_PROCESSING + 1);
     47     private static final String SERIES_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
     48             "DB Query", "DB Write", "HTTP Response", "HTTP Processing",};
     49     private static final Color SERIES_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
     50             Color.ORANGE, Color.RED, Color.CYAN, Color.PINK, Color.DARK_GRAY};
     51     private static final double SERIES_YCOORD[] = {0, 0, 0, 0, 1, 1, 2, 2};
     52 
     53     // Values from data/etc/event-log-tags
     54     private static final int EVENT_DB_OPERATION = 52000;
     55     private static final int EVENT_HTTP_STATS = 52001;
     56     // op types for EVENT_DB_OPERATION
     57     final int EVENT_DB_QUERY = 0;
     58     final int EVENT_DB_WRITE = 1;
     59 
     60     // Information to graph for each authority
     61     private TimePeriodValues mDatasets[];
     62 
     63     /**
     64      * TimePeriodValuesCollection that supports Y intervals.  This allows the
     65      * creation of "floating" bars, rather than bars rooted to the axis.
     66      */
     67     class YIntervalTimePeriodValuesCollection extends TimePeriodValuesCollection {
     68         /** default serial UID */
     69         private static final long serialVersionUID = 1L;
     70 
     71         private double yheight;
     72 
     73         /**
     74          * Constructs a collection of bars with a fixed Y height.
     75          *
     76          * @param yheight The height of the bars.
     77          */
     78         YIntervalTimePeriodValuesCollection(double yheight) {
     79             this.yheight = yheight;
     80         }
     81 
     82         /**
     83          * Returns ending Y value that is a fixed amount greater than the starting value.
     84          *
     85          * @param series the series (zero-based index).
     86          * @param item   the item (zero-based index).
     87          * @return The ending Y value for the specified series and item.
     88          */
     89         @Override
     90         public Number getEndY(int series, int item) {
     91             return getY(series, item).doubleValue() + yheight;
     92         }
     93     }
     94 
     95     /**
     96      * Constructs a graph of network and database stats.
     97      *
     98      * @param name The name of this graph in the graph list.
     99      */
    100     public DisplaySyncPerf(String name) {
    101         super(name);
    102     }
    103 
    104     /**
    105      * Creates the UI for the event display.
    106      *
    107      * @param parent    the parent composite.
    108      * @param logParser the current log parser.
    109      * @return the created control (which may have children).
    110      */
    111     @Override
    112     public Control createComposite(final Composite parent, EventLogParser logParser,
    113             final ILogColumnListener listener) {
    114         Control composite = createCompositeChart(parent, logParser, "Sync Performance");
    115         resetUI();
    116         return composite;
    117     }
    118 
    119     /**
    120      * Resets the display.
    121      */
    122     @Override
    123     void resetUI() {
    124         super.resetUI();
    125         XYPlot xyPlot = mChart.getXYPlot();
    126         xyPlot.getRangeAxis().setVisible(false);
    127         mTooltipGenerator = new CustomXYToolTipGenerator();
    128         mTooltips = new List[NUM_SERIES];
    129 
    130         XYBarRenderer br = new XYBarRenderer();
    131         br.setUseYInterval(true);
    132         mDatasets = new TimePeriodValues[NUM_SERIES];
    133 
    134         TimePeriodValuesCollection tpvc = new YIntervalTimePeriodValuesCollection(1);
    135         xyPlot.setDataset(tpvc);
    136         xyPlot.setRenderer(br);
    137 
    138         for (int i = 0; i < NUM_SERIES; i++) {
    139             br.setSeriesPaint(i, SERIES_COLORS[i]);
    140             mDatasets[i] = new TimePeriodValues(SERIES_NAMES[i]);
    141             tpvc.addSeries(mDatasets[i]);
    142             mTooltips[i] = new ArrayList<String>();
    143             mTooltipGenerator.addToolTipSeries(mTooltips[i]);
    144             br.setSeriesToolTipGenerator(i, mTooltipGenerator);
    145         }
    146     }
    147 
    148     /**
    149      * Updates the display with a new event.
    150      *
    151      * @param event     The event
    152      * @param logParser The parser providing the event.
    153      */
    154     @Override
    155     void newEvent(EventContainer event, EventLogParser logParser) {
    156         super.newEvent(event, logParser); // Handle sync operation
    157         try {
    158             if (event.mTag == EVENT_DB_OPERATION) {
    159                 // 52000 db_operation (name|3),(op_type|1|5),(time|2|3)
    160                 String tip = event.getValueAsString(0);
    161                 long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
    162                 int opType = Integer.parseInt(event.getValueAsString(1));
    163                 long duration = Long.parseLong(event.getValueAsString(2));
    164 
    165                 if (opType == EVENT_DB_QUERY) {
    166                     mDatasets[DB_QUERY].add(new SimpleTimePeriod(endTime - duration, endTime),
    167                             SERIES_YCOORD[DB_QUERY]);
    168                     mTooltips[DB_QUERY].add(tip);
    169                 } else if (opType == EVENT_DB_WRITE) {
    170                     mDatasets[DB_WRITE].add(new SimpleTimePeriod(endTime - duration, endTime),
    171                             SERIES_YCOORD[DB_WRITE]);
    172                     mTooltips[DB_WRITE].add(tip);
    173                 }
    174             } else if (event.mTag == EVENT_HTTP_STATS) {
    175                 // 52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
    176                 String tip = event.getValueAsString(0) + ", tx:" + event.getValueAsString(3) +
    177                         ", rx: " + event.getValueAsString(4);
    178                 long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
    179                 long netEndTime = endTime - Long.parseLong(event.getValueAsString(2));
    180                 long netStartTime = netEndTime - Long.parseLong(event.getValueAsString(1));
    181                 mDatasets[HTTP_NETWORK].add(new SimpleTimePeriod(netStartTime, netEndTime),
    182                         SERIES_YCOORD[HTTP_NETWORK]);
    183                 mDatasets[HTTP_PROCESSING].add(new SimpleTimePeriod(netEndTime, endTime),
    184                         SERIES_YCOORD[HTTP_PROCESSING]);
    185                 mTooltips[HTTP_NETWORK].add(tip);
    186                 mTooltips[HTTP_PROCESSING].add(tip);
    187             }
    188         } catch (NumberFormatException e) {
    189             // This can happen when parsing events from froyo+ where the event with id 52000
    190             // as a completely different format. For now, skip this event if this happens.
    191         } catch (InvalidTypeException e) {
    192         }
    193     }
    194 
    195     /**
    196      * Callback from super.newEvent to process a sync event.
    197      *
    198      * @param event      The sync event
    199      * @param startTime  Start time (ms) of events
    200      * @param stopTime   Stop time (ms) of events
    201      * @param details    Details associated with the event.
    202      * @param newEvent   True if this event is a new sync event.  False if this event
    203      * @param syncSource
    204      */
    205     @Override
    206     void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
    207             String details, boolean newEvent, int syncSource) {
    208         if (newEvent) {
    209             mDatasets[auth].add(new SimpleTimePeriod(startTime, stopTime), SERIES_YCOORD[auth]);
    210         }
    211     }
    212 
    213     /**
    214      * Gets display type
    215      *
    216      * @return display type as an integer
    217      */
    218     @Override
    219     int getDisplayType() {
    220         return DISPLAY_TYPE_SYNC_PERF;
    221     }
    222 }
    223