Ver código fonte

added filtering for bar and line graph.

Julien Clauter 11 anos atrás
pai
commit
3616e37bc7

+ 2 - 2
res/layout/fragment_statistics.xml

@@ -86,9 +86,9 @@
             android:layout_height="wrap_content"
             android:id="@+id/FilterButton"
             android:src="@drawable/ic_filter"
-            android:layout_alignParentTop="true"
             android:visibility="invisible"
-            />
+            android:layout_alignParentTop="true"
+            android:layout_toLeftOf="@+id/plot_data_button" />
 
         <ImageButton
             style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"

+ 31 - 0
src/de/tudarmstadt/informatik/hostage/logging/UglyDbHelper.java

@@ -209,6 +209,37 @@ public class UglyDbHelper extends SQLiteOpenHelper {
 		return this.getUniqueDataEntryForKeyType(KEY_SSID, TABLE_BSSIDS);
 	}
 
+    public ArrayList<String> getUniqueESSIDRecordsForProtocol(String protocol){
+        return this.getUniqueIDForProtocol(KEY_SSID, protocol);
+    }
+    public ArrayList<String> getUniqueBSSIDRecordsForProtocol(String protocol){
+        return this.getUniqueIDForProtocol(KEY_BSSID, protocol);
+    }
+
+    private ArrayList<String> getUniqueIDForProtocol(String id, String protocol){
+        ArrayList<String> recordList = new ArrayList<String>();
+        String selectQuery = "SELECT DISTINCT " + id + " FROM " + TABLE_ATTACK_INFO + " JOIN " + TABLE_BSSIDS + " USING "+ "(" + id + ") " + " WHERE " + TABLE_ATTACK_INFO + "."+ KEY_PROTOCOL + " = " + "'" + protocol + "'"+ " ORDER BY " + id; // " NATURAL JOIN " + TABLE_ATTACK_INFO + " NATURAL JOIN " + TABLE_BSSIDS + " NATURAL JOIN " + TABLE_PORTS +
+
+
+        // ORDERED BY TIME
+        System.out.println(selectQuery);
+        SQLiteDatabase db = this.getReadableDatabase();
+        Cursor cursor = db.rawQuery(selectQuery, null);
+
+        // looping through all rows and adding to list
+        if (cursor.moveToFirst()) {
+            do {
+                String record = cursor.getString(0);
+                recordList.add(record);
+            } while (cursor.moveToNext());
+        }
+        cursor.close();
+
+        // return record list
+        db.close();
+        return recordList;
+    }
+
 	/**
 	 * Gets all non duplicate Data Entry For a specific KeyType ( e.g. BSSIDs).
 	 * @return A ArrayList with received Records.

+ 17 - 14
src/de/tudarmstadt/informatik/hostage/ui2/dialog/DateTimeDialogFragment.java

@@ -1,14 +1,5 @@
 package de.tudarmstadt.informatik.hostage.ui2.dialog;
 
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
-import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog.ChecklistDialogListener;
-
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -24,6 +15,13 @@ import android.widget.DatePicker.OnDateChangedListener;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
 
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
+
 @SuppressLint("ValidFragment")
 public class DateTimeDialogFragment extends DialogFragment implements OnDateChangedListener, OnTimeChangedListener {
     // Define constants for date-time picker.
@@ -124,15 +122,20 @@ public class DateTimeDialogFragment extends DialogFragment implements OnDateChan
     }
     private DateTimeDialogFragmentListener mListener;
 
+    public void setDateChangeListener(DateTimeDialogFragmentListener listener){
+        this.mListener = listener;
+    }
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         try {
-            
-            if (activity.getClass().equals(MainActivity.class)){
-            	mListener = (DateTimeDialogFragmentListener) (((MainActivity)activity).getDisplayedFragment());
-            } else {
-            	mListener = (DateTimeDialogFragmentListener) activity;
+            if (this.mListener == null){
+                if (activity.getClass().equals(MainActivity.class)){
+                    mListener = (DateTimeDialogFragmentListener) (((MainActivity)activity).getDisplayedFragment());
+                } else {
+                    mListener = (DateTimeDialogFragmentListener) activity;
+                }
             }
         } catch (ClassCastException e) {
             throw new ClassCastException(activity.toString()

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

@@ -38,17 +38,19 @@ 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.dialog.DateTimeDialogFragment;
 import de.tudarmstadt.informatik.hostage.ui2.helper.ColorSequenceGenerator;
 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;
+import de.tudarmstadt.informatik.hostage.ui2.popup.SplitPopupItem;
 
 /**
  * Created by Julien on 16.02.14.
  */
-public class StatisticsFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener {
+public class StatisticsFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener, DateTimeDialogFragment.DateTimeDialogFragmentListener {
 
     static final String FILTER_MENU_TITLE_BSSID = "BSSID";
     static final String FILTER_MENU_TITLE_ESSID = "ESSID";
@@ -56,6 +58,10 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     static final String FILTER_MENU_TITLE_TIMESTAMP_BELOW = "Latest";
     static final String FILTER_MENU_TITLE_TIMESTAMP_ABOVE = "Earliest";
 
+    static final String FILTER_MENU_TITLE_REMOVE = "Reset Filter";
+    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";
@@ -251,9 +257,15 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         if (this.currentPlotView != null){
             if (type == ChartType.PIE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof PieGraph);
+                // SET FILTER BUTTON HIDDEN
+                ImageButton filterButton = this.getFilterButton();
+                if (filterButton != null) filterButton.setVisibility(View.INVISIBLE);
             } else {
                 if (this.pieGraph != null)
                      this.pieGraph.setVisibility(View.INVISIBLE);
+                // SHOW FILTER BUTTON
+                ImageButton filterButton = this.getFilterButton();
+                if (filterButton != null) filterButton.setVisibility(View.VISIBLE);
             }
             if (type == ChartType.LINE_CHART){
                 shouldChange = ! (this.currentPlotView instanceof LineGraph);
@@ -263,15 +275,11 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             }
             if (type == ChartType.BAR_CHART){
                 shouldChange = ! (this.currentPlotView instanceof BarGraph);
-                // SHOW FILTER BUTTON
-                ImageButton filterButton = this.getFilterButton();
-                if (filterButton != null) filterButton.setVisibility(View.VISIBLE);
+
             } else {
                 if (this.barGraph != null)
                     this.barGraph.setVisibility(View.INVISIBLE);
-                // SET FILTER BUTTON HIDDEN
-                ImageButton filterButton = this.getFilterButton();
-                if (filterButton != null) filterButton.setVisibility(View.INVISIBLE);
+
             }
         }
         if (shouldChange){
@@ -327,7 +335,11 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     private void userSelectMenuItem(AbstractPopupItem item){
         // OPEN A DIALOG TO SPECIFY THE VISUALISE DATA
         if (item.getTitle().equals(MENU_TITLE_PROTOCOLS)){
-            this.openProtocolDataDialog();
+            ChartType chartType = ChartType.PIE_CHART;
+            this.selectedCompareData = COMPARE_TITLE_AttacksPerProtocol;
+            this.setChartType(chartType);
+            this.setTitle(COMPARE_TITLE_AttacksPerProtocol);
+            //this.openProtocolDataDialog();
         }
         if (item.getTitle().equals(MENU_TITLE_NETWORK)){
             this.openNetworkDataDialog();
@@ -380,6 +392,16 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             this.setTitle(fragTitle);
             return;
         }
+        if (title.equals(FILTER_MENU_TITLE_ESSID)){
+            this.filter.setESSIDs(titles);
+            this.actualiseCurrentPlot();
+            return;
+        }
+        if (title.equals(FILTER_MENU_TITLE_BSSID)){
+            this.filter.setBSSIDs(titles);
+            this.actualiseCurrentPlot();
+            return;
+        }
 
         if (titles.size() != 0){
             String data = titles.get(0);
@@ -428,8 +450,8 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     }
     private ArrayList<String> getDialogNetworkDataTitle(){
         ArrayList<String> data = new ArrayList<String>();
-        data.add(COMPARE_TITLE_AttacksPerBSSID);
         data.add(COMPARE_TITLE_AttacksPerESSID);
+        data.add(COMPARE_TITLE_AttacksPerBSSID);
         return data;
     }
     private boolean[] selectedData(ArrayList<String> data){
@@ -445,6 +467,94 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     *
     * */
     private void openFilterMenuOnView(View anchor){
+        SimplePopupTable filterMenu = new SimplePopupTable(this.getActivity(), new AbstractPopup.OnPopupItemClickListener() {
+            public void onItemClick(Object ob) {
+                if (ob instanceof  AbstractPopupItem){
+                    AbstractPopupItem item = (AbstractPopupItem) ob;
+                    StatisticsFragment.this.onFilterMenuItemSelected(item);
+                }
+            }
+        });
+
+        filterMenu.setTitle(FILTER_MENU_POPUP_TITLE);
+        for(String title : StatisticsFragment.this.filterMenuTitles()){
+            AbstractPopupItem item = null;
+            if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_BELOW)) continue;
+            if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_ABOVE)){
+                item = new SplitPopupItem(this.getActivity());
+                item.setValue(SplitPopupItem.RIGHT_TITLE, FILTER_MENU_TITLE_TIMESTAMP_BELOW);
+                item.setValue(SplitPopupItem.LEFT_TITLE, FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+                if (this.filter.hasBelowTimestamp()){
+                    item.setValue(SplitPopupItem.RIGHT_SUBTITLE, this.getDateAsString(this.filter.belowTimestamp));
+                }
+                if (this.filter.hasAboveTimestamp()){
+                    item.setValue(SplitPopupItem.LEFT_SUBTITLE, this.getDateAsString(this.filter.aboveTimestamp));
+                }
+            } else {
+                item = new SimplePopupItem(this.getActivity());
+                item.setTitle(title);
+                ((SimplePopupItem)item).setSelected(this.isFilterSetForTitle(title));
+            }
+
+            filterMenu.addItem(item);
+        }
+        filterMenu.showOnView(anchor);
+    }
+
+    private void onFilterMenuItemSelected(AbstractPopupItem item){
+        if (item instanceof SplitPopupItem){
+            SplitPopupItem sItem = (SplitPopupItem) item;
+            this.wasBelowTimePicker = sItem.wasRightTouch;
+            if (this.wasBelowTimePicker){
+                this.openTimestampToFilterDialog();
+            } else {
+                this.openTimestampFromFilterDialog();
+            }
+            return;
+        }
+        String title = item.getTitle();
+        if (title.equals(FILTER_MENU_TITLE_ESSID)){
+            this.openESSIDFilterDialog();
+        }
+        if (title.equals(FILTER_MENU_TITLE_BSSID)){
+            this.openBSSIDFilterDialog();
+        }
+        if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)){
+            this.openFilterDialogSelectProtocol();
+        }
+        if (title.equals(FILTER_MENU_TITLE_REMOVE)){
+            this.clearFilter();
+            this.actualiseCurrentPlot();
+        }
+    }
+
+    private ArrayList<String> filterMenuTitles(){
+        ArrayList<String> titles = new ArrayList<String>();
+        if (this.currentPlotView instanceof LineGraph){
+            titles.add(FILTER_MENU_TITLE_ESSID);
+            titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+            if (this.filter.hasESSIDs() || this.filter.hasATimestamp()){
+                titles.add(FILTER_MENU_TITLE_REMOVE);
+            }
+        } else {
+            titles.add(FILTER_MENU_TITLE_PROTOCOLS);
+            String protocol = this.getCurrentSelectedProtocol();
+            if (protocol.length() > 0){
+                if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerBSSID)){
+                    titles.add(FILTER_MENU_TITLE_BSSID);
+                }
+                // DEFAULT
+                titles.add(FILTER_MENU_TITLE_ESSID);
+            }
+            titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+            if (this.filter.hasProtocols() || this.filter.hasATimestamp() || this.filter.hasESSIDs() || this.filter.hasBSSIDs()){
+                titles.add(FILTER_MENU_TITLE_REMOVE);
+            }
+        }
+        return titles;
+    }
+
+    private void openFilterDialogSelectProtocol(){
         ArrayList<String> titles = this.protocolTitles();
         boolean[] selected = new boolean[titles.size()];
         int i = 0;
@@ -454,9 +564,95 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         }
         ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE, titles, selected, false , this);
         newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE);
+    }
+
+    private void openESSIDFilterDialog(){
+        ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_ESSID, this.essids(), this.selectedESSIDs(), true , this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_ESSID);
+    }
+
+    private void openBSSIDFilterDialog(){
+        ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_BSSID, this.bssids(), this.selectedBSSIDs(), true , this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_BSSID);
+    }
+
+    private void openTimestampFromFilterDialog(){
+        this.wasBelowTimePicker = false;
+        DateTimeDialogFragment newFragment = new DateTimeDialogFragment(this.getActivity());
+        newFragment.setDateChangeListener(this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_TIMESTAMP_ABOVE);
+
+        if (this.filter.aboveTimestamp != Long.MIN_VALUE)newFragment.setDate(this.filter.aboveTimestamp);
+    }
+
+    private void openTimestampToFilterDialog(){
+        this.wasBelowTimePicker = true;
+        DateTimeDialogFragment newFragment = new DateTimeDialogFragment(this.getActivity());
+        newFragment.setDateChangeListener(this);
+        newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_TIMESTAMP_BELOW);
+        if (this.filter.belowTimestamp != Long.MAX_VALUE) newFragment.setDate(this.filter.belowTimestamp);
+    }
+
+    public ArrayList<String> essids(){
+        ArrayList<String> records;
+        if (this.currentPlotView instanceof BarGraph){
+            records = dbh.getUniqueESSIDRecordsForProtocol(this.getCurrentSelectedProtocol());
+        } else {
+            records = dbh.getUniqueESSIDRecords();
+        }
+        return records;
+    }
+    public boolean[] selectedESSIDs(){
+        ArrayList<String> essids = this.essids();
+        boolean[] selected = new boolean[essids.size()];
+
+        int i = 0;
+        for(String essid : essids){
+            selected[i] =(this.filter.getESSIDs().contains(essid));
+            i++;
+        }
+        return selected;
+    }
+
+    public ArrayList<String> bssids(){
+        ArrayList<String> records ;
+        if (this.currentPlotView instanceof BarGraph){
+            records = dbh.getUniqueBSSIDRecordsForProtocol(this.getCurrentSelectedProtocol());
+        } else {
+            records = dbh.getUniqueBSSIDRecords();
+        }
+        return records;
+    }
+    public boolean[] selectedBSSIDs(){
+        ArrayList<String> bssids = this.bssids();
+
+        boolean[] selected = new boolean[bssids.size()];
+
+        int i = 0;
+        for(String bssid : bssids){
+            selected[i] =(this.filter.getBSSIDs().contains(bssid));
+            i++;
+        }
+        return selected;
+    }
 
+    public void onDateTimePickerPositiveClick(DateTimeDialogFragment dialog) {
+        if(this.wasBelowTimePicker){
+            this.filter.setBelowTimestamp(dialog.getDate());
+        } else {
+            this.filter.setAboveTimestamp(dialog.getDate());
+        }
+        this.actualiseCurrentPlot();
     }
 
+    public void onDateTimePickerNegativeClick(DateTimeDialogFragment dialog) {
+        if(this.wasBelowTimePicker){
+            this.filter.setBelowTimestamp(Long.MAX_VALUE);
+        } else {
+            this.filter.setAboveTimestamp(Long.MIN_VALUE);
+        }
+        this.actualiseCurrentPlot();
+    }
 
     /**
     *
@@ -689,9 +885,6 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
      }
 
     public ArrayList<PlotComparisonItem> getPieData(){
-        if (this.selectedCompareData.equals(COMPARE_TITLE_UsesPerProtocol)){
-            return this.usesPerProtocol();
-        }
         // DEFAULT
         return this.attacksPerProtocols();
     }
@@ -699,11 +892,11 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         String protocol = this.getCurrentSelectedProtocol();
 
         if (protocol.length() > 0){
-            if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerBSSID)){
-                return this.attacksPerBSSID(protocol);
+            if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerESSID)){
+                return this.attacksPerESSID(protocol);
             }
             // DEFAULT
-            return this.attacksPerESSID(protocol);
+            return this.attacksPerBSSID(protocol);
         }
         // Nothing available
         return new ArrayList<PlotComparisonItem>();
@@ -735,23 +928,6 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
          });
          return this.resizeData(plotItems);
     }
-    public ArrayList<PlotComparisonItem> usesPerProtocol(){
-        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
-            public int compare(PlotComparisonItem s1, PlotComparisonItem s2) {
-                return s1.getTitle().compareToIgnoreCase(s2.getTitle());
-            }
-        });
-        return plotItems;
-    }
     /*LINE PLOT DATA*/
 
     public ArrayList<PlotComparisonItem> attacksPerTime(){
@@ -828,6 +1004,9 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     public ArrayList<PlotComparisonItem> attacksPerBSSID(String protocol){
         LogFilter filter = new LogFilter();
         ArrayList<String> protocollist = new ArrayList<String>();
+        filter.setAboveTimestamp(this.filter.getAboveTimestamp());
+        filter.setBelowTimestamp(this.filter.getBelowTimestamp());
+        filter.setBSSIDs(this.filter.getBSSIDs());
         protocollist.add(protocol);
         filter.setProtocols(protocollist);
 
@@ -861,6 +1040,9 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     }
     public ArrayList<PlotComparisonItem> attacksPerESSID(String protocol){
         LogFilter filter = new LogFilter();
+        filter.setAboveTimestamp(this.filter.getAboveTimestamp());
+        filter.setBelowTimestamp(this.filter.getBelowTimestamp());
+        filter.setESSIDs(this.filter.getESSIDs());
         ArrayList<String> protocollist = new ArrayList<String>();
         protocollist.add(protocol);
         filter.setProtocols(protocollist);
@@ -892,7 +1074,7 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
             }
         });
 
-        return plotItems;// this.resizeData(plotItems);
+        return this.resizeData(plotItems);
     }
 
 
@@ -1063,6 +1245,18 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
         }
     }
 
+    @SuppressLint("SimpleDateFormat")
+    private String getDateAsString(long timeStamp) {
+
+        try {
+            DateFormat sdf = new SimpleDateFormat("H:mm  dd/MM/yyyy");
+            Date netDate = (new Date(timeStamp));
+            return sdf.format(netDate);
+        } catch (Exception ex) {
+            return "xx";
+        }
+    }
+
 
     /**
      * USERINTERACTION
@@ -1101,4 +1295,5 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
 
     }
 
+
 }