• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Control;
23 import org.jfree.chart.plot.XYPlot;
24 import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
25 import org.jfree.chart.renderer.xy.XYBarRenderer;
26 import org.jfree.data.time.RegularTimePeriod;
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.util.Calendar;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.TimeZone;
36 
37 public class DisplaySyncHistogram extends SyncCommon {
38 
39     Map<SimpleTimePeriod, Integer> mTimePeriodMap[];
40 
41     // Information to graph for each authority
42     private TimePeriodValues mDatasetsSyncHist[];
43 
DisplaySyncHistogram(String name)44     public DisplaySyncHistogram(String name) {
45         super(name);
46     }
47 
48     /**
49      * Creates the UI for the event display.
50      * @param parent the parent composite.
51      * @param logParser the current log parser.
52      * @return the created control (which may have children).
53      */
54     @Override
createComposite(final Composite parent, EventLogParser logParser, final ILogColumnListener listener)55     public Control createComposite(final Composite parent, EventLogParser logParser,
56             final ILogColumnListener listener) {
57         Control composite = createCompositeChart(parent, logParser, "Sync Histogram");
58         resetUI();
59         return composite;
60     }
61 
62     /**
63      * Resets the display.
64      */
65     @Override
resetUI()66     void resetUI() {
67         super.resetUI();
68         XYPlot xyPlot = mChart.getXYPlot();
69 
70         AbstractXYItemRenderer br = new XYBarRenderer();
71         mDatasetsSyncHist = new TimePeriodValues[NUM_AUTHS+1];
72         mTimePeriodMap = new HashMap[NUM_AUTHS + 1];
73 
74         TimePeriodValuesCollection tpvc = new TimePeriodValuesCollection();
75         xyPlot.setDataset(tpvc);
76         xyPlot.setRenderer(br);
77 
78         for (int i = 0; i < NUM_AUTHS + 1; i++) {
79             br.setSeriesPaint(i, AUTH_COLORS[i]);
80             mDatasetsSyncHist[i] = new TimePeriodValues(AUTH_NAMES[i]);
81             tpvc.addSeries(mDatasetsSyncHist[i]);
82             mTimePeriodMap[i] = new HashMap<SimpleTimePeriod, Integer>();
83 
84         }
85     }
86 
87     /**
88      * Callback to process a sync event.
89      *
90      * @param event      The sync event
91      * @param startTime Start time (ms) of events
92      * @param stopTime Stop time (ms) of events
93      * @param details Details associated with the event.
94      * @param newEvent True if this event is a new sync event.  False if this event
95      * @param syncSource
96      */
97     @Override
processSyncEvent(EventContainer event, int auth, long startTime, long stopTime, String details, boolean newEvent, int syncSource)98     void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
99             String details, boolean newEvent, int syncSource) {
100         if (newEvent) {
101             if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
102                 auth = ERRORS;
103             }
104             double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
105             addHistEvent(0, auth, delta);
106         } else {
107             // sync_details arrived for an event that has already been graphed.
108             if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
109                 // Item turns out to be in error, so transfer time from old auth to error.
110                 double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
111                 addHistEvent(0, auth, -delta);
112                 addHistEvent(0, ERRORS, delta);
113             }
114         }
115     }
116 
117     /**
118      * Helper to add an event to the data series.
119      * Also updates error series if appropriate (x or X in details).
120      * @param stopTime Time event ends
121      * @param auth Sync authority
122      * @param value Value to graph for event
123      */
addHistEvent(long stopTime, int auth, double value)124     private void addHistEvent(long stopTime, int auth, double value) {
125         SimpleTimePeriod hour = getTimePeriod(stopTime, mHistWidth);
126 
127         // Loop over all datasets to do the stacking.
128         for (int i = auth; i <= ERRORS; i++) {
129             addToPeriod(mDatasetsSyncHist, i, hour, value);
130         }
131     }
132 
addToPeriod(TimePeriodValues tpv[], int auth, SimpleTimePeriod period, double value)133     private void addToPeriod(TimePeriodValues tpv[], int auth, SimpleTimePeriod period,
134             double value) {
135         int index;
136         if (mTimePeriodMap[auth].containsKey(period)) {
137             index = mTimePeriodMap[auth].get(period);
138             double oldValue = tpv[auth].getValue(index).doubleValue();
139             tpv[auth].update(index, oldValue + value);
140         } else {
141             index = tpv[auth].getItemCount();
142             mTimePeriodMap[auth].put(period, index);
143             tpv[auth].add(period, value);
144         }
145     }
146 
147     /**
148      * Creates a multiple-hour time period for the histogram.
149      * @param time Time in milliseconds.
150      * @param numHoursWide: should divide into a day.
151      * @return SimpleTimePeriod covering the number of hours and containing time.
152      */
getTimePeriod(long time, long numHoursWide)153     private SimpleTimePeriod getTimePeriod(long time, long numHoursWide) {
154         Date date = new Date(time);
155         TimeZone zone = RegularTimePeriod.DEFAULT_TIME_ZONE;
156         Calendar calendar = Calendar.getInstance(zone);
157         calendar.setTime(date);
158         long hoursOfYear = calendar.get(Calendar.HOUR_OF_DAY) +
159                 calendar.get(Calendar.DAY_OF_YEAR) * 24;
160         int year = calendar.get(Calendar.YEAR);
161         hoursOfYear = (hoursOfYear / numHoursWide) * numHoursWide;
162         calendar.clear();
163         calendar.set(year, 0, 1, 0, 0); // Jan 1
164         long start = calendar.getTimeInMillis() + hoursOfYear * 3600 * 1000;
165         return new SimpleTimePeriod(start, start + numHoursWide * 3600 * 1000);
166     }
167 
168     /**
169      * Gets display type
170      *
171      * @return display type as an integer
172      */
173     @Override
getDisplayType()174     int getDisplayType() {
175         return DISPLAY_TYPE_SYNC_HIST;
176     }
177 }
178