/* (C) 2012 Pragmatic Software This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ */ package com.googlecode.networklog; import android.os.Bundle; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.shapes.Shape; import android.graphics.drawable.shapes.RectShape; import android.graphics.drawable.ShapeDrawable; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.jjoe64.graphview.GraphView.GraphViewData; import com.jjoe64.graphview.GraphView.GraphViewSeries; public class OverallAppTimelineGraph extends GraphActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); graphView.setTitle(getString(R.string.graph_apps_timeline)); buildSeries(interval, viewsize); } public void buildSeries(double timeFrameSize, double viewSize) { if(instanceData != null) { graphView.graphSeries = instanceData.graphSeries; } else { HashMap<Integer, ArrayList<PacketGraphItem>> appMap = new HashMap<Integer, ArrayList<PacketGraphItem>>(); HashMap<Integer, String> uidNameMap = new HashMap<Integer, String>(); ArrayList<PacketGraphItem> packetList; graphView.graphSeries.clear(); if(NetworkLog.logFragment == null || NetworkLog.logFragment.listData == null || NetworkLog.logFragment.listData.size() == 0) { SysUtils.showError(this, getString(R.string.graph_error_nodata_title), getString(R.string.graph_error_nodata_text)); finish(); return; } synchronized(NetworkLog.logFragment.listData) { for(LogFragment.ListItem item : NetworkLog.logFragment.listData) { packetList = appMap.get(item.app.uid); if(packetList == null) { packetList = new ArrayList<PacketGraphItem>(); appMap.put(item.app.uid, packetList); uidNameMap.put(item.app.uid, "(" + item.app.uid + ") " + item.app.name); } packetList.add(new PacketGraphItem(item.timestamp, item.len)); } } if(appMap.size() == 0) { SysUtils.showError(this, getString(R.string.graph_error_nodata_title), getString(R.string.graph_error_nodata_text)); finish(); return; } int color = 0; float density = getResources().getDisplayMetrics().density; Shape rect = new RectShape(); int intrinsicLength = (int)(18 * (density + 0.5)); int uid; for(Map.Entry<Integer, ArrayList<PacketGraphItem>> entry : appMap.entrySet()) { uid = entry.getKey(); packetList = entry.getValue(); if(MyLog.enabled) { MyLog.d("number of packets for " + uid + ": " + packetList.size()); } ArrayList<PacketGraphItem> graphData = new ArrayList<PacketGraphItem>(); double nextTimeFrame = 0; double frameLen = 1; // len for this time frame for(PacketGraphItem data : packetList) { if(nextTimeFrame == 0) { // first plot graphData.add(new PacketGraphItem(data.timestamp - 1, 1)); graphData.add(new PacketGraphItem(data.timestamp, data.len)); // set up first time frame nextTimeFrame = data.timestamp + timeFrameSize; frameLen = data.len; // get next data continue; } if(data.timestamp <= nextTimeFrame) { // data within current time frame, add to frame len frameLen += data.len; // get next data continue; } else { // data outside current time frame // signifies end of frame // plot frame len graphData.add(new PacketGraphItem(nextTimeFrame, frameLen)); // set up next time frame nextTimeFrame += timeFrameSize; frameLen = 1; // test for gap if(data.timestamp > nextTimeFrame) { // data is past this time frame, plot zero here graphData.add(new PacketGraphItem(nextTimeFrame, frameLen)); if((data.timestamp - timeFrameSize) > nextTimeFrame) { graphData.add(new PacketGraphItem(data.timestamp - timeFrameSize, 1)); } nextTimeFrame = data.timestamp; frameLen = data.len; graphData.add(new PacketGraphItem(nextTimeFrame, frameLen)); nextTimeFrame += timeFrameSize; frameLen = 1; continue; } else { // data is within this frame, add len frameLen = data.len; } } } graphData.add(new PacketGraphItem(nextTimeFrame, frameLen)); graphData.add(new PacketGraphItem(nextTimeFrame + timeFrameSize, 1)); GraphViewData[] seriesData = new GraphViewData[graphData.size()]; int i = 0; for(PacketGraphItem graphItem : graphData) { seriesData[i] = new GraphViewData(graphItem.timestamp, graphItem.len); i++; } int hashCode = String.valueOf(uid).hashCode(); String name = uidNameMap.get(uid); graphView.addSeries(new GraphViewSeries(hashCode, name, Color.parseColor(getResources().getString(Colors.distinctColor[color])), seriesData)); boolean enabled = true; boolean exists = false; for(LegendItem legend : legendData) { if(legend.mHashCode == hashCode) { enabled = legend.mEnabled; exists = true; break; } } if(exists == false) { ShapeDrawable shape = new ShapeDrawable(rect); shape.getPaint().setColor(Color.parseColor(getResources().getString(Colors.distinctColor[color]))); shape.setIntrinsicWidth(intrinsicLength); shape.setIntrinsicHeight(intrinsicLength); LegendItem legend = new LegendItem(); legend.mIcon = shape; legend.mHashCode = hashCode; legend.mName = name; legend.mEnabled = true; legendData.add(legend); } graphView.setSeriesEnabled(hashCode, enabled); color++; if(color >= Colors.distinctColor.length) { color = 0; } } } double minX = graphView.getMinX(true); double maxX = graphView.getMaxX(true); double viewStart = maxX - viewSize; if(instanceData != null) { viewStart = instanceData.viewportStart; viewSize = instanceData.viewsize; } if(viewStart < minX) { viewStart = minX; } if(viewStart + viewSize > maxX) { viewSize = maxX - viewStart; } graphView.setViewPort(viewStart, viewSize); graphView.invalidateLabels(); graphView.invalidate(); } }