Browse Source

fixed bugs in statisticfragment and added other plot types

Julien Clauter 10 years ago
parent
commit
0e89fe1616

+ 3 - 0
res/drawable-xhdpi/popup_background.xml

@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/popup_black"/>

BIN
res/drawable-xhdpi/popup_black.9.png


BIN
res/drawable-xhdpi/popup_black.png


+ 1 - 18
res/layout/fragment_statistics.xml

@@ -94,30 +94,13 @@
             style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:id="@+id/PiePlotButton"
+            android:id="@+id/plot_data_button"
             android:src="@drawable/ic_sort_by_size"
             android:layout_gravity="right"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
             android:layout_alignParentEnd="true"/>
 
-        <ImageButton
-            style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:id="@+id/LinePlotButton"
-            android:src="@drawable/ic_filter"
-            android:layout_alignParentTop="true"
-            android:layout_toLeftOf="@+id/BarPlotButton"/>
-
-        <ImageButton
-            style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:id="@+id/BarPlotButton"
-            android:src="@drawable/ic_device_access_storage"
-            android:layout_alignParentTop="true"
-            android:layout_toLeftOf="@+id/PiePlotButton"/>
     </RelativeLayout>
 
 

+ 11 - 1
src/com/echo/holographlibrary/BarGraph.java

@@ -95,7 +95,17 @@ public class BarGraph extends View {
             mFullImage = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
             Canvas canvas = new Canvas(mFullImage);
             canvas.drawColor(Color.TRANSPARENT);
-            NinePatchDrawable popup = (NinePatchDrawable)this.getResources().getDrawable(popupImageID);
+
+            /*
+            Bitmap backMap = BitmapFactory.decodeResource(getResources(), this.popupImageID);
+            backMap = backMap.copy(Bitmap.Config.ARGB_8888, true);
+            byte[] chunk = backMap.getNinePatchChunk();
+            NinePatchDrawable popup = new NinePatchDrawable(getResources(), backMap, chunk, new Rect(), null);
+            popup.setBounds(0, 0, backMap.getWidth(), backMap.getHeight());
+            */
+
+
+            NinePatchDrawable popup = (NinePatchDrawable)this.getResources().getDrawable(this.popupImageID);
             
             float maxValue = 0;
             float padding = 7 * mContext.getResources().getDisplayMetrics().density;

+ 3 - 0
src/de/tudarmstadt/informatik/hostage/ui2/dialog/ChecklistDialog.java

@@ -95,6 +95,9 @@ public class ChecklistDialog extends DialogFragment {
     	for(Integer i : this.mSelectedItems){
     		list.add(this.itemTitles.get(i.intValue()));
     	}
+        if (this.mSelectedItems.size() == 0){
+            list.add(this.itemTitles.get(this.selectedIndex));
+        }
     	return list;
     }
 	

+ 228 - 25
src/de/tudarmstadt/informatik/hostage/ui2/fragment/StatisticsFragment.java

@@ -10,6 +10,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
+import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
@@ -36,29 +37,46 @@ import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper;
 import de.tudarmstadt.informatik.hostage.ui.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui2.adapter.StatisticListAdapter;
+import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog;
 import de.tudarmstadt.informatik.hostage.ui2.model.PlotComparisonItem;
+import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopup;
+import de.tudarmstadt.informatik.hostage.ui2.popup.AbstractPopupItem;
+import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupItem;
+import de.tudarmstadt.informatik.hostage.ui2.popup.SimplePopupTable;
 
 /**
  * Created by Julien on 16.02.14.
  */
-public class StatisticsFragment extends Fragment {
-    static final String SELECTED_KEY = "Selected";
-    static final String OTHERS_KEY = "Other";
+public class StatisticsFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener {
 
     static final String FILTER_MENU_TITLE_BSSID = "BSSID";
     static final String FILTER_MENU_TITLE_ESSID = "ESSID";
     static final String FILTER_MENU_TITLE_PROTOCOLS = "Protocol";
     static final String FILTER_MENU_TITLE_TIMESTAMP_BELOW = "Latest";
     static final String FILTER_MENU_TITLE_TIMESTAMP_ABOVE = "Earliest";
-    static final String FILTER_MENU_TITLE_SORTING = "Sort by";
-    static final String FILTER_MENU_TITLE_REMOVE = "Reset Filter";
-    static final String FILTER_MENU_TITLE_GROUP = "Group by";
-    static final String FILTER_MENU_POPUP_TITLE = "Filter by";
+
+    static final String MENU_TITLE_PROTOCOLS = "Protocols";
+    static final String MENU_TITLE_NETWORK = "Networks";
+    static final String MENU_TITLE_ATTACKS = "Attacks";
+
+    static final String MENU_POPUP_TITLE = "Visualise:";
 
     static final String CHART_TYPE_TITLE_BAR = "Bar Plot";
     static final String CHART_TYPE_TITLE_PIE = "Pie Plot";
     static final String CHART_TYPE_TITLE_LINE = "Line Plot";
 
+    static final String DIALOG_PROTOCOLS_TITLE = "Select protocol data to compare";
+    static final String DIALOG_NETWORK_TITLE = "Select network data to compare";
+    static final String DIALOG_ATTACK_TITLE = "Select attack data to compare";
+
+    static  final String COMPARE_TITLE_AttacksPerProtocol   = "Attacks per protocol";
+    static  final String COMPARE_TITLE_UsesPerProtocol      = "Uses per protocol";
+    static  final String COMPARE_TITLE_AttacksPerDate       = "Attacks per date";
+    static  final String COMPARE_TITLE_AttacksPerTime       = "Attacks per time";
+    static  final String COMPARE_TITLE_AttacksPerBSSID      = "Attacks per BSSID";
+    static  final String COMPARE_TITLE_AttacksPerESSID      = "Attacks per ESSID";
+
+
     static final String OTHER_CHART_TITLE = "Other";
 
     // MINIMAL 2
@@ -84,6 +102,8 @@ public class StatisticsFragment extends Fragment {
 
     private ListView legendListView;
 
+    private String selectedCompareData = COMPARE_TITLE_AttacksPerProtocol;
+
     public enum ChartType {
         PIE_CHART(0),
         BAR_CHART(1),
@@ -177,6 +197,13 @@ public class StatisticsFragment extends Fragment {
         plotLayout.removeAllViews();
 
         this.actualiseCurrentPlot();
+
+        ImageButton filterButton = (ImageButton) rootView.findViewById(R.id.plot_data_button);
+        filterButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                StatisticsFragment.this.openPopupMenuOnView(v);
+            }
+        });
     }
 
     public void setTitle(String title){
@@ -206,17 +233,22 @@ public class StatisticsFragment extends Fragment {
             if (type == ChartType.PIE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof PieGraph);
             } else {
-                this.pieGraph.setVisibility(View.INVISIBLE);
+                if (this.pieGraph != null)
+                     this.pieGraph.setVisibility(View.INVISIBLE);
             }
             if (type == ChartType.LINE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof LineGraph);
             } else {
-                this.lineGraph.setVisibility(View.INVISIBLE);
+                if (this.lineGraph != null)
+                     this.lineGraph.setVisibility(View.INVISIBLE);
             }
             if (type == ChartType.BAR_CHART){
                 shouldChange = ! (this.currentPlotView instanceof BarGraph);
+                // SHOW FILTER BUTTON
             } else {
-                this.barGraph.setVisibility(View.INVISIBLE);
+                if (this.barGraph != null)
+                    this.barGraph.setVisibility(View.INVISIBLE);
+                // SET FILTER BUTTON HIDDEN
             }
         }
         if (shouldChange){
@@ -243,6 +275,135 @@ public class StatisticsFragment extends Fragment {
         this.legendListView.setAdapter(adapter);
     }
 
+    /*
+    * MENU
+    * */
+    private void openPopupMenuOnView(View anchorView){
+        SimplePopupTable visualiseMenu = new SimplePopupTable(this.getActivity(), new AbstractPopup.OnPopupItemClickListener() {
+            public void onItemClick(Object ob) {
+                if (ob instanceof AbstractPopupItem){
+                    AbstractPopupItem item = (AbstractPopupItem) ob;
+                    StatisticsFragment.this.userSelectMenuItem(item);
+                }
+            }
+        });
+        visualiseMenu.setTitle(MENU_POPUP_TITLE);
+        int id = 0;
+        for(String title : StatisticsFragment.this.getMenuTitles()){
+            SimplePopupItem item = new SimplePopupItem(this.getActivity());
+            item.setTitle(title);
+            item.setItemId(id);
+            item.setSelected(this.isFilterSetForTitle(title));
+            visualiseMenu.addItem(item);
+            id++;
+        }
+        visualiseMenu.showOnView(anchorView);
+    }
+
+    private void userSelectMenuItem(AbstractPopupItem item){
+        //int id = item.getItemId();
+        //this.setChartType(ChartType.create(id));
+        // OPEN A DIALOG TO SPECIFY THE VISUALISE DATA
+        if (item.getTitle().equals(MENU_TITLE_PROTOCOLS)){
+            this.openProtocolDataDialog();
+        }
+        if (item.getTitle().equals(MENU_TITLE_NETWORK)){
+            this.openNetworkDataDialog();
+        }
+        if (item.getTitle().equals(MENU_TITLE_ATTACKS)){
+            this.openAttackDataDialog();
+        }
+    }
+
+    private ArrayList<String> getMenuTitles(){
+        ArrayList<String> titles = new ArrayList<String>();
+        titles.add(MENU_TITLE_PROTOCOLS);
+        titles.add(MENU_TITLE_NETWORK);
+        titles.add(MENU_TITLE_ATTACKS);
+        return titles;
+    }
+
+    /*
+    * PLOT DATA DIALOGS
+    * */
+    private void openProtocolDataDialog(){
+        ArrayList<String> titles = this.getDialogProtocolDataTitle();
+        ChecklistDialog newFragment = new ChecklistDialog(DIALOG_PROTOCOLS_TITLE, titles, this.selectedData(titles), false , this);
+        newFragment.show(this.getActivity().getFragmentManager(), DIALOG_PROTOCOLS_TITLE);
+    }
+    private void openNetworkDataDialog(){
+        ArrayList<String> titles = this.getDialogNetworkDataTitle();
+        ChecklistDialog newFragment = new ChecklistDialog(DIALOG_NETWORK_TITLE, titles, this.selectedData(titles), false , this);
+        newFragment.show(this.getActivity().getFragmentManager(), DIALOG_NETWORK_TITLE);
+    }
+    private void openAttackDataDialog(){
+        ArrayList<String> titles = this.getDialogAttackDataTitle();
+        ChecklistDialog newFragment = new ChecklistDialog(DIALOG_ATTACK_TITLE, titles, this.selectedData(titles), false , this);
+        newFragment.show(this.getActivity().getFragmentManager(), DIALOG_ATTACK_TITLE);
+    }
+
+    /*
+    *
+    * DIALOG ACTION METHODS
+    *
+    * */
+    public void onDialogPositiveClick(ChecklistDialog dialog) {
+        String title = dialog.getTitle();
+        ArrayList<String> titles =dialog.getSelectedItemTitles();
+        if (titles.size() != 0){
+            String data = titles.get(0);
+
+            if (title.equals(DIALOG_PROTOCOLS_TITLE)){
+                ChartType chartType = ChartType.PIE_CHART;
+                this.selectedCompareData = data;
+                this.setChartType(chartType);
+            }
+            if (title.equals(DIALOG_ATTACK_TITLE)){
+                ChartType chartType = ChartType.LINE_CHART;
+                this.selectedCompareData = data;
+                this.setChartType(chartType);
+            }
+            if (title.equals(DIALOG_NETWORK_TITLE)){
+                ChartType chartType = ChartType.BAR_CHART;
+                this.selectedCompareData = data;
+                this.setChartType(chartType);
+            }
+        }
+    }
+
+    public void onDialogNegativeClick(ChecklistDialog dialog) {
+
+    }
+    /*
+    *
+    * DIALOG DATA
+    *
+    * */
+    private ArrayList<String> getDialogProtocolDataTitle(){
+        ArrayList<String> data = new ArrayList<String>();
+        data.add(COMPARE_TITLE_AttacksPerProtocol);
+        data.add(COMPARE_TITLE_UsesPerProtocol);
+        return data;
+    }
+    private ArrayList<String> getDialogAttackDataTitle(){
+        ArrayList<String> data = new ArrayList<String>();
+        data.add(COMPARE_TITLE_AttacksPerDate);
+        data.add(COMPARE_TITLE_AttacksPerTime);
+        return data;
+    }
+    private ArrayList<String> getDialogNetworkDataTitle(){
+        ArrayList<String> data = new ArrayList<String>();
+        data.add(COMPARE_TITLE_AttacksPerBSSID);
+        data.add(COMPARE_TITLE_AttacksPerESSID);
+        return data;
+    }
+    private boolean[] selectedData(ArrayList<String> data){
+        boolean[] selected = new boolean[data.size()];
+         // SET DEFAULT
+        selected[0] = true;
+        return selected;
+    }
+
     /**
     *
     * PLOT TOUCH HANDLING
@@ -287,6 +448,7 @@ public class StatisticsFragment extends Fragment {
         if (this.barGraph == null) {
             this.barGraph = new BarGraph(this.getActivity());
             LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout);
+            this.barGraph.setLayoutParams(new ViewGroup.LayoutParams(plotLayout.getWidth(), plotLayout.getHeight()));
             plotLayout.addView(this.barGraph);
             this.barGraph.setPopupImageID(R.drawable.popup_black);
             this.barGraph.setOnBarClickedListener(new BarGraph.OnBarClickedListener() {
@@ -324,7 +486,7 @@ public class StatisticsFragment extends Fragment {
     }
 
     public void setLineGraphData(LineGraph linegraph){
-        this.currentData = this.getLinedata();
+        this.currentData = this.getLineData();
         if (this.currentData == null){
             this.currentData = new ArrayList<PlotComparisonItem>();
         }
@@ -347,7 +509,7 @@ public class StatisticsFragment extends Fragment {
     }
 
     public void setBarGraphData(BarGraph bargraph){
-        this.currentData = this.getLinedata();
+        this.currentData = this.getBarData();
         if (this.currentData == null){
             this.currentData = new ArrayList<PlotComparisonItem>();
         }
@@ -360,6 +522,7 @@ public class StatisticsFragment extends Fragment {
             d.setName(item.getTitle());
             Double value2 = (Double) item.getValue2();
             d.setValue(value2.floatValue());
+            bars.add(d);
         }
 
         this.barGraph.setBars(bars);
@@ -378,6 +541,7 @@ public class StatisticsFragment extends Fragment {
 
 
      public void actualiseCurrentPlot(){
+         LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout);
         View plot = this.currentPlotView;
          if (plot == null){
              this.currentPlotView = this.getPieGraphView();
@@ -389,36 +553,54 @@ public class StatisticsFragment extends Fragment {
             PieGraph pie = (PieGraph) plot;
             this.setPieGraphData(pie);
         } else {
-            if (this.pieGraph != null)
+            if (this.pieGraph != null){
                 this.pieGraph.setVisibility(View.INVISIBLE);
+                if (this.pieGraph.getParent() != null){
+                    plotLayout.removeView(this.pieGraph);
+                }
+            }
         }
         if (plot instanceof BarGraph){
             BarGraph bar = (BarGraph) plot;
             this.setBarGraphData(bar);
         } else {
-            if (this.barGraph != null)
+            if (this.barGraph != null){
                 this.barGraph.setVisibility(View.INVISIBLE);
+                if (this.barGraph.getParent() != null){
+                    plotLayout.removeView(this.barGraph);
+                }
+            }
         }
         if (plot instanceof LineGraph){
            LineGraph line = (LineGraph)plot;
            this.setLineGraphData(line);
         }else {
-            if (this.lineGraph != null)
+            if (this.lineGraph != null){
                 this.lineGraph.setVisibility(View.INVISIBLE);
+                if (this.lineGraph.getParent() != null){
+                    plotLayout.removeView(this.lineGraph);
+                }
+            }
         }
         plot.setVisibility(View.VISIBLE);
+         if (plot.getParent() == null){
+             plotLayout.addView(plot);
+         }
          this.actualiseLegendList();
+         this.currentPlotView.bringToFront();
          this.currentPlotView.invalidate();
      }
 
     public ArrayList<PlotComparisonItem> getPieData(){
+        if (this.selectedCompareData.equals(COMPARE_TITLE_UsesPerProtocol)){
+            return this.usesPerProtocol();
+        }
         // DEFAULT
         return this.attacksPerProtocols();
     }
     public ArrayList<PlotComparisonItem> getBarData(){
         ArrayList<String> protocolTitles = this.getSelectedProtocolTitles();
 
-        // DEFAULT
         if (protocolTitles != null && protocolTitles.size() != 0){
             String protocol = this.getSelectedProtocolTitles().get(0);
             return this.attacksPerBSSID(protocol);
@@ -427,13 +609,16 @@ public class StatisticsFragment extends Fragment {
         // Nothing available
         return new ArrayList<PlotComparisonItem>();
     }
-    public ArrayList<PlotComparisonItem> getLinedata(){
+    public ArrayList<PlotComparisonItem> getLineData(){
+        if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerTime)){
+            return this.attacksPerTime();
+        }
         // DEFAULT
         return this.attacksPerDate();
     }
 
     /*
-    * SPECIFIC DATA STUFF
+    *  DATA SOURCE
     * */
 
     /*PROTOCOLS OVERVIEW*/
@@ -442,6 +627,7 @@ public class StatisticsFragment extends Fragment {
          int index = 0;
         for (String title : this.getSelectedProtocolTitles()){
             int attacksCount = this.dbh.getAttackPerProtocolCount(title);
+            if (attacksCount == 0) continue;
             PlotComparisonItem item = new PlotComparisonItem(title,this.getColor(index), 0., (double) attacksCount);
             plotItems.add(item);
             index++;
@@ -458,7 +644,10 @@ public class StatisticsFragment extends Fragment {
         ArrayList<PlotComparisonItem> plotItems = new ArrayList<PlotComparisonItem>();
         for (String title : this.getSelectedProtocolTitles()){
             /*At the moment there is no possibillity to get the number of uses for each protocol*/
-
+            // TODO GET USES PER PROTOCOL
+            int uses = 0;
+            if (uses == 0) continue;
+            // ADD ITEMS
         }
         Collections.sort(plotItems, new Comparator<PlotComparisonItem>() {
             @Override
@@ -474,7 +663,7 @@ public class StatisticsFragment extends Fragment {
         HashMap<Long, ArrayList<Record> > recordMap = new HashMap<Long, ArrayList<Record> >();
 
         for (Record record : this.getFetchedRecords()){
-            long date = this.getdateFromMilliseconds(record.getTimestamp());
+            long date = this.getDateFromMilliseconds(record.getTimestamp());
             ArrayList<Record> list = recordMap.get(date);
             if (list == null){
                 list = new ArrayList<Record>();
@@ -485,6 +674,7 @@ public class StatisticsFragment extends Fragment {
         int index = 0;
         for (long date : recordMap.keySet()){
             ArrayList<Record> list = recordMap.get(date);
+            if (list.size() == 0) continue;
             PlotComparisonItem item = new PlotComparisonItem(this.getDateAsDayString(date), this.getColor(index), (double) date, (double)list.size());
             plotItems.add(item);
             index++;
@@ -513,6 +703,7 @@ public class StatisticsFragment extends Fragment {
         int index = 0;
         for (long time : recordMap.keySet()){
             ArrayList<Record> list = recordMap.get(time);
+            if (list.size() == 0) continue;
             PlotComparisonItem item = new PlotComparisonItem(this.getDateAsTimeString(time), this.getColor(index) , (double)time, (double) list.size());
             plotItems.add(item);
             index++;
@@ -537,13 +728,18 @@ public class StatisticsFragment extends Fragment {
         HashMap<String, Integer> recordMap = new HashMap<String, Integer>();
         ArrayList<Record> records = this.dbh.getRecordsForFilter(filter);
         for (Record record : records){
-            int count = recordMap.get(record.getBssid());
+            int count = 0;
+            if (recordMap.containsKey(record.getBssid())){
+                count = recordMap.get(record.getBssid());
+            }
             count++;
             recordMap.put(record.getBssid(), count);
         }
         int index = 0;
         for (String key : recordMap.keySet()){
-            PlotComparisonItem item = new PlotComparisonItem(key, this.getColor(index), 0., (double)recordMap.get(key));
+            double value = (double)recordMap.get(key);
+            if (value == 0.) continue;
+            PlotComparisonItem item = new PlotComparisonItem(key, this.getColor(index), 0., value);
             plotItems.add(item);
             index++;
         }
@@ -566,13 +762,18 @@ public class StatisticsFragment extends Fragment {
         HashMap<String, Integer> recordMap = new HashMap<String, Integer>();
         ArrayList<Record> records = this.dbh.getRecordsForFilter(filter);
         for (Record record : records){
-            int count = recordMap.get(record.getSsid());
+            int count = 0;
+            if (recordMap.containsKey(record.getSsid())){
+                count = recordMap.get(record.getSsid());
+            }
             count++;
             recordMap.put(record.getSsid(), count);
         }
         int index = 0;
         for (String key : recordMap.keySet()){
-            PlotComparisonItem item = new PlotComparisonItem(key,this.getColor(index), 0. , (double)recordMap.get(key));
+            double value =  (double)recordMap.get(key);
+            if (value == 0.) continue;
+            PlotComparisonItem item = new PlotComparisonItem(key,this.getColor(index), 0. ,value);
             plotItems.add(item);
             index++;
         }
@@ -754,7 +955,7 @@ public class StatisticsFragment extends Fragment {
 
         return (hour*60*60)*1000;
     }
-    public long getdateFromMilliseconds(long timeInMillis){
+    public long getDateFromMilliseconds(long timeInMillis){
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis (timeInMillis);
 
@@ -815,6 +1016,8 @@ public class StatisticsFragment extends Fragment {
             if (this.currentPlotView instanceof  LineGraph){
                 // TODO set data for BSSID / ESSID
             }
+
+            this.pushRecordOverviewForFilter(filter);
         }