package de.tudarmstadt.informatik.hostage.ui2.fragment; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import android.annotation.SuppressLint; import android.app.Fragment; import android.app.FragmentManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Color; import android.os.Bundle; 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; import com.echo.holographlibrary.Bar; import com.echo.holographlibrary.BarGraph; import com.echo.holographlibrary.Line; import com.echo.holographlibrary.LineGraph; import com.echo.holographlibrary.LinePoint; import com.echo.holographlibrary.PieGraph; import com.echo.holographlibrary.PieSlice; import de.tudarmstadt.informatik.hostage.R; import de.tudarmstadt.informatik.hostage.logging.Record; import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper; import de.tudarmstadt.informatik.hostage.ui.LogFilter; import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity; 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, DateTimeDialogFragment.DateTimeDialogFragmentListener { static final String FILTER_MENU_TITLE_BSSID = "BSSID"; static final String FILTER_MENU_TITLE_ESSID = "ESSID"; static final String FILTER_MENU_TITLE_PROTOCOLS = MainActivity.getContext().getString(R.string.stats_protocols); static final String FILTER_MENU_TITLE_PROTOCOL = MainActivity.getContext().getString(R.string.rec_protocol); static final String FILTER_MENU_TITLE_TIMESTAMP_BELOW = MainActivity.getContext().getString(R.string.rec_latest); static final String FILTER_MENU_TITLE_TIMESTAMP_ABOVE = MainActivity.getContext().getString(R.string.rec_earliest); static final String FILTER_MENU_TITLE_REMOVE = MainActivity.getContext().getString(R.string.rec_reset_filter); static final String FILTER_MENU_POPUP_TITLE = MainActivity.getContext().getString(R.string.rec_filter_by); static final String MENU_TITLE_PROTOCOLS = MainActivity.getContext().getString(R.string.stats_protocols); static final String MENU_TITLE_NETWORK = MainActivity.getContext().getString(R.string.stats_networks); static final String MENU_TITLE_ATTACKS = MainActivity.getContext().getString(R.string.stats_attacks); static final String MENU_POPUP_TITLE = MainActivity.getContext().getString(R.string.stats_visualize); static final String CHART_TYPE_TITLE_BAR = MainActivity.getContext().getString(R.string.stats_bar_plot); static final String CHART_TYPE_TITLE_PIE = MainActivity.getContext().getString(R.string.stats_pie_plot); static final String CHART_TYPE_TITLE_LINE = MainActivity.getContext().getString(R.string.stats_line_plot); static final String DIALOG_PROTOCOLS_TITLE = MainActivity.getContext().getString(R.string.stats_select_protocol_data); static final String DIALOG_NETWORK_TITLE = MainActivity.getContext().getString(R.string.stats_select_network_data); static final String DIALOG_ATTACK_TITLE = MainActivity.getContext().getString(R.string.stats_select_attack_data); static final String COMPARE_TITLE_AttacksPerProtocol = MainActivity.getContext().getString(R.string.stats_attacks_protocol); static final String COMPARE_TITLE_UsesPerProtocol = MainActivity.getContext().getString(R.string.stats_uses_protocol); static final String COMPARE_TITLE_AttacksPerDate = MainActivity.getContext().getString(R.string.stats_attacks_date); static final String COMPARE_TITLE_AttacksPerTime = MainActivity.getContext().getString(R.string.stats_attacks_time); static final String COMPARE_TITLE_AttacksPerBSSID = MainActivity.getContext().getString(R.string.stats_attacks_bssid); static final String COMPARE_TITLE_AttacksPerESSID = MainActivity.getContext().getString(R.string.stats_attacks_essid); static final String FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE = MainActivity.getContext().getString(R.string.stats_select_protocol); static final String TABLE_HEADER_VALUE_TITLE_ATTACKS_COUNT = MainActivity.getContext().getString(R.string.stats_attacks_count); static final String TABLE_HEADER_VALUE_TITLE_ATTACKS_PERCENTAGE = MainActivity.getContext().getString(R.string.stats_per_cent_all); static final String OTHER_CHART_TITLE = MainActivity.getContext().getString(R.string.stats_other); // MINIMAL 2 static int MAX_NUMBER_OF_CHART_OBJECTS = 6; private boolean wasBelowTimePicker; private LogFilter filter; private boolean showFilterButton; private PieGraph pieGraph; private LineGraph lineGraph; private BarGraph barGraph; private View rootView; private View currentPlotView; private ArrayList colorList; private ArrayList currentData; private HostageDBOpenHelper dbh; private ListView legendListView; private String selectedCompareData = COMPARE_TITLE_AttacksPerProtocol; public enum ChartType { PIE_CHART(0), BAR_CHART(1), LINE_CHART(2); private int value; private ChartType(int value) { this.value = value; } static public ChartType create(int value) { if (value < 0 || value >= ChartType.values().length) return ChartType.PIE_CHART; return ChartType.values()[value]; } public String toString() { if (this.equals(ChartType.create(0))) { return CHART_TYPE_TITLE_PIE; } if (this.equals(ChartType.create(1))) { return CHART_TYPE_TITLE_BAR; } return CHART_TYPE_TITLE_LINE; } } private ImageButton getFilterButton() { return (ImageButton) this.rootView.findViewById(R.id.FilterButton); } public int getLayoutID() { return R.layout.fragment_statistics; } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); getActivity().setTitle(getResources().getString(R.string.drawer_statistics)); dbh = new HostageDBOpenHelper(this.getBaseContext()); // Get the message from the intent if (this.filter == null) { Intent intent = this.getActivity().getIntent(); LogFilter filter = intent.getParcelableExtra(LogFilter.LOG_FILTER_INTENT_KEY); if (filter == null) { this.clearFilter(); } else { this.filter = filter; } } this.rootView = inflater.inflate(this.getLayoutID(), container, false); this.configureRootView(this.rootView); return this.rootView; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); setRetainInstance(true); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); LayoutInflater inflater = LayoutInflater.from(getActivity()); ViewGroup container = (ViewGroup) this.getView(); container.removeAllViewsInLayout(); this.rootView = inflater.inflate(this.getLayoutID(), container, false); container.addView(this.rootView); this.configureRootView(this.rootView); } private Context getBaseContext() { return this.getActivity().getBaseContext(); } private Context getApplicationContext() { return this.getActivity().getApplicationContext(); } public void configureRootView(View rootView) { LinearLayout plotLayout = (LinearLayout) rootView.findViewById(R.id.plot_layout); plotLayout.setWillNotDraw(false); plotLayout.removeAllViews(); plotLayout.setWillNotDraw(false); this.legendListView = (ListView) rootView.findViewById(R.id.legend_list_view); this.legendListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { StatisticsFragment.this.userTappedOnLegendItem(i); } }); rootView.setWillNotDraw(false); this.actualiseCurrentPlot(); ImageButton visualButton = (ImageButton) rootView.findViewById(R.id.plot_data_button); visualButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { StatisticsFragment.this.openBarSelectionMenuOnView(v); } }); ImageButton filterButton = this.getFilterButton(); filterButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { StatisticsFragment.this.openFilterMenuOnView(v); } }); if (this.currentPlotView instanceof BarGraph) { this.setTitle("" + this.getCurrentSelectedProtocol() + ": " + this.selectedCompareData); } else { this.setTitle(this.selectedCompareData); } } public void setTitle(String title) { TextView titleView = (TextView) this.rootView.findViewById(R.id.title_text_view); if (title != null && titleView != null) { titleView.setText(title); titleView.invalidate(); } } public String getTitle() { TextView titleView = (TextView) this.rootView.findViewById(R.id.title_text_view); if (titleView != null) { return "" + titleView.getText(); } return ""; } public void onStart() { super.onStart(); this.actualiseCurrentPlot(); this.currentPlotView.invalidate(); if (this.currentPlotView instanceof BarGraph) { this.setTitle("" + this.getCurrentSelectedProtocol() + ": " + this.selectedCompareData); } else { this.setTitle(this.selectedCompareData); } } public void setChartType(ChartType type) { boolean shouldChange = true; this.clearFilter(); 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.GONE); } else { if (this.pieGraph != null) this.pieGraph.setVisibility(View.GONE); // SHOW FILTER BUTTON ImageButton filterButton = this.getFilterButton(); if (filterButton != null) filterButton.setVisibility(View.VISIBLE); } if (type == ChartType.LINE_CHART) { shouldChange = !(this.currentPlotView instanceof LineGraph); } else { if (this.lineGraph != null) this.lineGraph.setVisibility(View.GONE); } if (type == ChartType.BAR_CHART) { shouldChange = !(this.currentPlotView instanceof BarGraph); } else { if (this.barGraph != null) this.barGraph.setVisibility(View.GONE); } } if (shouldChange) { this.currentPlotView = this.getPlotViewForType(type); this.currentPlotView.setVisibility(View.VISIBLE); } this.actualiseCurrentPlot(); } public View getPlotViewForType(ChartType type) { switch (type) { case PIE_CHART: return this.getPieGraphView(); case LINE_CHART: return this.getLineGraphView(); default: return this.getBarGraphView(); } } public void actualiseLegendList() { StatisticListAdapter adapter = new StatisticListAdapter(this.getApplicationContext(), this.currentData); if (this.currentPlotView instanceof LineGraph) { adapter.setValueFormatter(new StatisticListAdapter.ValueFormatter() { @Override public String convertValueForItemToString(PlotComparisonItem item) { return String.format("%.02f", item.getValue2()) + " %" + " " + "(" + (item.getValue1().intValue()) + ")"; } }); } else { adapter.setValueFormatter(new StatisticListAdapter.ValueFormatter() { @Override public String convertValueForItemToString(PlotComparisonItem item) { int v = (int) item.getValue2().intValue(); return "" + v; } }); } this.legendListView.setAdapter(adapter); TextView tableHeaderTitleView = (TextView) this.rootView.findViewById(R.id.table_header_title_textview); TextView tableHeaderValueView = (TextView) this.rootView.findViewById(R.id.table_header_value_textview); if (this.currentPlotView instanceof LineGraph) { tableHeaderTitleView.setText(FILTER_MENU_TITLE_ESSID); tableHeaderValueView.setText(TABLE_HEADER_VALUE_TITLE_ATTACKS_PERCENTAGE); } if (this.currentPlotView instanceof PieGraph) { tableHeaderTitleView.setText(FILTER_MENU_TITLE_PROTOCOL); tableHeaderValueView.setText(TABLE_HEADER_VALUE_TITLE_ATTACKS_COUNT); } if (this.currentPlotView instanceof BarGraph) { tableHeaderValueView.setText(TABLE_HEADER_VALUE_TITLE_ATTACKS_COUNT); if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerBSSID)) { tableHeaderTitleView.setText(FILTER_MENU_TITLE_BSSID); } else { tableHeaderTitleView.setText(FILTER_MENU_TITLE_ESSID); } } } /* * MENU */ private void openBarSelectionMenuOnView(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(false); visualiseMenu.addItem(item); id++; } visualiseMenu.showOnView(anchorView); } private void userSelectMenuItem(AbstractPopupItem item) { // OPEN A DIALOG TO SPECIFY THE VISUALISE DATA if (item.getTitle().equals(MENU_TITLE_PROTOCOLS)) { ChartType chartType = ChartType.PIE_CHART; this.selectedCompareData = COMPARE_TITLE_AttacksPerProtocol; this.setChartType(chartType); this.setTitle(COMPARE_TITLE_AttacksPerProtocol); } if (item.getTitle().equals(MENU_TITLE_NETWORK)) { this.openNetworkDataDialog(); } if (item.getTitle().equals(MENU_TITLE_ATTACKS)) { this.openAttackDataDialog(); } } private ArrayList getMenuTitles() { ArrayList titles = new ArrayList(); titles.add(MENU_TITLE_PROTOCOLS); titles.add(MENU_TITLE_NETWORK); titles.add(MENU_TITLE_ATTACKS); return titles; } /* * PLOT DATA DIALOGS */ private void openProtocolDataDialog() { ArrayList 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 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 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 titles = dialog.getSelectedItemTitles(); if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)) { // titles = titles.size() == 0 ? this.protocolTitles() : titles; this.filter.setProtocols(titles); this.actualiseCurrentPlot(); return; } if (title.equals(FILTER_MENU_PROTOCOL_SINGLE_CHOICE_TITLE)) { if (titles.size() == 0) { titles = new ArrayList(); titles.add(this.protocolTitles().get(0)); } this.filter.setProtocols(titles); this.actualiseCurrentPlot(); String fragTitle = "" + this.getCurrentSelectedProtocol() + ": " + this.selectedCompareData; 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); this.setTitle(data); 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); String fragTitle = "" + this.getCurrentSelectedProtocol() + ": " + this.selectedCompareData; this.setTitle(fragTitle); } } } public void onDialogNegativeClick(ChecklistDialog dialog) { } /* * * DIALOG DATA */ private ArrayList getDialogProtocolDataTitle() { ArrayList data = new ArrayList(); data.add(COMPARE_TITLE_AttacksPerProtocol); data.add(COMPARE_TITLE_UsesPerProtocol); return data; } private ArrayList getDialogAttackDataTitle() { ArrayList data = new ArrayList(); data.add(COMPARE_TITLE_AttacksPerDate); data.add(COMPARE_TITLE_AttacksPerTime); return data; } private ArrayList getDialogNetworkDataTitle() { ArrayList data = new ArrayList(); data.add(COMPARE_TITLE_AttacksPerESSID); data.add(COMPARE_TITLE_AttacksPerBSSID); return data; } private boolean[] selectedData(ArrayList data) { boolean[] selected = new boolean[data.size()]; // SET DEFAULT selected[0] = true; return selected; } /* * * FILTER BUTTON */ 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_PROTOCOL)) { this.openFilterDialogSelectProtocol(); } if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)) { this.openProtocolsFilterDialog(); } if (title.equals(FILTER_MENU_TITLE_REMOVE)) { this.clearFilter(); this.actualiseCurrentPlot(); } } private ArrayList filterMenuTitles() { ArrayList titles = new ArrayList(); if (this.currentPlotView instanceof LineGraph) { titles.add(FILTER_MENU_TITLE_ESSID); titles.add(FILTER_MENU_TITLE_PROTOCOLS); titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE); if (this.filter.hasESSIDs() || this.filter.hasATimestamp() || (this.filter.getProtocols() != null && this.filter.hasProtocols() && this.filter.getProtocols().size() != this.protocolTitles().size())) { titles.add(FILTER_MENU_TITLE_REMOVE); } } else { titles.add(FILTER_MENU_TITLE_PROTOCOL); String protocol = this.getCurrentSelectedProtocol(); if (protocol.length() > 0) { if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerBSSID)) { titles.add(FILTER_MENU_TITLE_BSSID); } else { // DEFAULT titles.add(FILTER_MENU_TITLE_ESSID); } } titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE); if (this.filter.hasATimestamp() || this.filter.hasESSIDs() || this.filter.hasBSSIDs() || (this.currentPlotView instanceof LineGraph && this.filter.hasProtocols())) { titles.add(FILTER_MENU_TITLE_REMOVE); } } return titles; } private void openProtocolsFilterDialog() { ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_PROTOCOLS, this.protocolTitles(), this.selectedProtocols(), true, this); newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_PROTOCOLS); } private void openFilterDialogSelectProtocol() { ArrayList titles = this.protocolTitles(); boolean[] selected = new boolean[titles.size()]; int i = 0; for (String title : titles) { selected[i] = title.equals(this.getCurrentSelectedProtocol()); i++; } 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 essids() { ArrayList records; if (this.currentPlotView instanceof BarGraph) { records = dbh.getUniqueESSIDRecordsForProtocol(this.getCurrentSelectedProtocol()); } else { records = dbh.getUniqueESSIDRecords(); } return records; } public boolean[] selectedESSIDs() { ArrayList 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 bssids() { ArrayList records; if (this.currentPlotView instanceof BarGraph) { records = dbh.getUniqueBSSIDRecordsForProtocol(this.getCurrentSelectedProtocol()); } else { records = dbh.getUniqueBSSIDRecords(); } return records; } public boolean[] selectedBSSIDs() { ArrayList 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(); } /* * * PLOT TYPES * * * */ public PieGraph getPieGraphView() { if (this.pieGraph == null) { this.pieGraph = new PieGraph(this.getApplicationContext()); LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout); plotLayout.addView(this.pieGraph); this.pieGraph.setOnSliceClickedListener(new PieGraph.OnSliceClickedListener() { @Override public void onClick(int index) { StatisticsFragment.this.onSliceClick(index); } }); } return this.pieGraph; } public LineGraph getLineGraphView() { if (this.lineGraph == null) { this.lineGraph = new LineGraph(this.getActivity()); LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout); plotLayout.addView(this.lineGraph); this.lineGraph.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); } return this.lineGraph; } public BarGraph getBarGraphView() { if (this.barGraph == null) { this.barGraph = new BarGraph(this.getActivity()); LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout); this.barGraph.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); plotLayout.addView(this.barGraph); this.barGraph.setShowBarText(false); this.barGraph.setPopupImageID(R.drawable.popup_black); this.barGraph.setOnBarClickedListener(new BarGraph.OnBarClickedListener() { @Override public void onClick(int i) { StatisticsFragment.this.onBarClick(i); } }); } return this.barGraph; } /* * FEED PLOTS WITH DATA */ public void setPieGraphData(PieGraph piegraph) { this.currentData = this.getPieData(); if (this.currentData == null) { this.currentData = new ArrayList(); } this.pieGraph.removeSlices(); for (PlotComparisonItem item : this.currentData) { PieSlice slice = new PieSlice(); slice.setColor(item.getColor()); Double value2 = (Double) item.getValue2(); float v = value2.floatValue(); slice.setValue(v); slice.setTitle(item.getTitle()); this.pieGraph.addSlice(slice); } this.pieGraph.invalidate(); } public void setLineGraphData(LineGraph linegraph) { this.currentData = this.getLineData(); if (this.currentData == null) { this.currentData = new ArrayList(); } this.lineGraph.removeAllLines(); double rangeMax_Y = 0; double rangeMin_Y = 0; double rangeMax_X = 0; double rangeMin_X = 0; int count = 0; for (PlotComparisonItem lineItem : this.currentData) { ArrayList data = lineItem.getOtherData(); int index = 0; Line l = new Line(); int lineColor = lineItem.getColor(); l.setColor(lineColor); for (PlotComparisonItem pointItem : data) { LinePoint p = new LinePoint(); p.setX(pointItem.getValue1()); Double value2 = pointItem.getValue2(); p.setY(value2); p.setColor(lineColor); l.addPoint(p); rangeMax_Y = Math.max(pointItem.getValue2(), rangeMax_Y); rangeMax_X = Math.max(pointItem.getValue1(), rangeMax_X); if (count != 0) { rangeMin_Y = Math.min(pointItem.getValue2(), rangeMin_Y); rangeMin_X = Math.min(pointItem.getValue1(), rangeMin_X); } else { rangeMin_Y = pointItem.getValue2(); rangeMin_X = pointItem.getValue1(); } index++; count++; } this.lineGraph.addLine(l); } // add a bit more space rangeMax_Y++; rangeMin_Y--; boolean shouldUseDate = this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerDate); if (shouldUseDate) { this.lineGraph.resetXLimits(); if (this.filter.hasBelowTimestamp()) { rangeMax_X = Math.max(this.filter.belowTimestamp, rangeMax_X); } if (this.filter.hasAboveTimestamp()) { rangeMin_X = Math.min(this.filter.aboveTimestamp, rangeMin_X); } double stepRange = (rangeMax_X - rangeMin_X) / (60 * 60 * 24 * 1000); this.lineGraph.setxAxisStep(Math.max(1, (float) Math.min(stepRange, 4))); this.lineGraph.setRangeX(rangeMin_X, rangeMax_X); this.lineGraph.setConverter(new LineGraph.AxisDataConverter() { @Override public String convertDataForX_Position(double x) { return StatisticsFragment.this.getDateAsDayString((long) x); } @Override public String convertDataForY_Position(double y) { return "" + (long) y; } }); } else { this.lineGraph.setxAxisStep(12.f); this.lineGraph.setRangeX(0, 24); this.lineGraph.setConverter(null); } int maxY = (int) (rangeMax_Y - rangeMin_Y); this.lineGraph.setYAxisStep(Math.min(maxY, 5)); int yStep = (int) this.lineGraph.getyAxisStep(); if ((maxY % yStep) != 0) { maxY = maxY + (yStep - (maxY % yStep)); } this.lineGraph.setRangeY(rangeMin_Y, rangeMin_Y + maxY); this.lineGraph.setLineToFill(0); this.lineGraph.invalidate(); } public void setBarGraphData(BarGraph bargraph) { this.currentData = this.getBarData(); if (this.currentData == null) { this.currentData = new ArrayList(); } ArrayList bars = new ArrayList(); for (PlotComparisonItem item : this.currentData) { Bar d = new Bar(); d.setColor(item.getColor()); Long value2 = item.getValue2().longValue(); d.setName("" + value2); d.setValue(value2.floatValue()); bars.add(d); } this.barGraph.setBars(bars); this.barGraph.invalidate(); } /* * * FETCH & ACTUALISE RECORD DATA */ public ArrayList getFetchedRecords() { if (this.filter == null) this.clearFilter(); return this.dbh.getRecordsForFilter(this.filter); } public void actualiseCurrentPlot() { LinearLayout plotLayout = (LinearLayout) this.rootView.findViewById(R.id.plot_layout); View plot = this.currentPlotView; if (plot == null) { this.currentPlotView = this.getPieGraphView(); plot = this.currentPlotView; } if (plot.getParent() != null && !plot.getParent().equals(plotLayout)) { LinearLayout linLayout = (LinearLayout) plot.getParent(); linLayout.removeView(plot); plot.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); plotLayout.addView(plot); } if (plot.getVisibility() == View.GONE) plot.setVisibility(View.VISIBLE); if (plot instanceof PieGraph) { PieGraph pie = (PieGraph) plot; this.setPieGraphData(pie); // HIDE FILTER BUTTON ImageButton filterButton = this.getFilterButton(); if (filterButton != null) filterButton.setVisibility(View.GONE); } else { if (this.pieGraph != null) { this.pieGraph.setVisibility(View.GONE); if (this.pieGraph.getParent() != null) { plotLayout.removeView(this.pieGraph); } } // SHOW FILTER BUTTON ImageButton filterButton = this.getFilterButton(); if (filterButton != null) filterButton.setVisibility(View.VISIBLE); } if (plot instanceof BarGraph) { BarGraph bar = (BarGraph) plot; this.setBarGraphData(bar); } else { if (this.barGraph != null) { this.barGraph.setVisibility(View.GONE); 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) { this.lineGraph.setVisibility(View.GONE); 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 getPieData() { // DEFAULT return this.attacksPerProtocols(); } public ArrayList getBarData() { String protocol = this.getCurrentSelectedProtocol(); if (protocol.length() > 0) { if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerESSID)) { return this.attacksPerESSID(protocol); } // DEFAULT return this.attacksPerBSSID(protocol); } // Nothing available return new ArrayList(); } public ArrayList getLineData() { return this.attacksPerTime(); } /* * DATA SOURCE */ /* PROTOCOLS OVERVIEW */ public ArrayList attacksPerProtocols() { ArrayList plotItems = new ArrayList(); 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++; } Collections.sort(plotItems, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s2.getValue2().compareTo(s1.getValue2()); } }); return this.resizeData(plotItems); } /* LINE PLOT DATA */ public ArrayList attacksPerTime() { HashMap>> lineMap = new HashMap>>(); boolean shouldUseDate = this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerDate); ArrayList records = this.getFetchedRecords(); for (Record record : records) { long timestamp = record.getTimestamp(); long time = 0; if (shouldUseDate) { time = this.getDateFromMilliseconds(timestamp); } else { time = this.getDayHourFromDate(timestamp); } // GET CORRECT MAP HashMap> recordMap; String groupKey = record.getSsid(); if (lineMap.containsKey(groupKey)) { recordMap = lineMap.get(record.getSsid()); } else { recordMap = new HashMap>(); lineMap.put(groupKey, recordMap); } // GET LIST OF RECORDS ArrayList list; if (recordMap.containsKey(time)) { list = recordMap.get(time); } else { list = new ArrayList(); recordMap.put(time, list); } list.add(record); } ArrayList plotItems = new ArrayList(); int index = 0; for (String groupKey : lineMap.keySet()) { HashMap> recordMap = lineMap.get(groupKey); ArrayList singleLineItems = new ArrayList(); int numbOfAttacks = 0; for (long time : recordMap.keySet()) { ArrayList list = recordMap.get(time); if (list.size() == 0) continue; PlotComparisonItem item = new PlotComparisonItem(this.getHourAsTimeString(time), 0, (double) time, (double) list.size()); singleLineItems.add(item); numbOfAttacks += list.size(); } Collections.sort(singleLineItems, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s1.getValue1().compareTo(s2.getValue1()); } }); double itemValue = (((double) numbOfAttacks / (double) records.size()) * 100.); PlotComparisonItem item = new PlotComparisonItem(groupKey, this.getColor(index), (double) numbOfAttacks, itemValue); item.setOtherData(singleLineItems); plotItems.add(item); index++; } Collections.sort(plotItems, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s2.getValue2().compareTo(s1.getValue2()); } }); return plotItems; } // BAR PLOT DATA public ArrayList attacksPerBSSID(String protocol) { LogFilter filter = new LogFilter(); ArrayList protocollist = new ArrayList(); filter.setAboveTimestamp(this.filter.getAboveTimestamp()); filter.setBelowTimestamp(this.filter.getBelowTimestamp()); filter.setBSSIDs(this.filter.getBSSIDs()); protocollist.add(protocol); filter.setProtocols(protocollist); ArrayList plotItems = new ArrayList(); HashMap recordMap = new HashMap(); ArrayList records = this.dbh.getRecordsForFilter(filter); for (Record record : records) { 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()) { double value = (double) recordMap.get(key); if (value == 0.) continue; PlotComparisonItem item = new PlotComparisonItem(key, this.getColor(index), 0., value); plotItems.add(item); index++; } Collections.sort(plotItems, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s2.getValue2().compareTo(s1.getValue2()); } }); return this.resizeData(plotItems); } public ArrayList attacksPerESSID(String protocol) { LogFilter filter = new LogFilter(); filter.setAboveTimestamp(this.filter.getAboveTimestamp()); filter.setBelowTimestamp(this.filter.getBelowTimestamp()); filter.setESSIDs(this.filter.getESSIDs()); ArrayList protocollist = new ArrayList(); protocollist.add(protocol); filter.setProtocols(protocollist); ArrayList plotItems = new ArrayList(); HashMap recordMap = new HashMap(); ArrayList records = this.dbh.getRecordsForFilter(filter); for (Record record : records) { 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()) { double value = (double) recordMap.get(key); if (value == 0.) continue; PlotComparisonItem item = new PlotComparisonItem(key, this.getColor(index), 0., value); plotItems.add(item); index++; } Collections.sort(plotItems, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s2.getValue2().compareTo(s1.getValue2()); } }); return this.resizeData(plotItems); } private ArrayList resizeData(ArrayList plotItems) { if (plotItems != null) { if (plotItems.size() > MAX_NUMBER_OF_CHART_OBJECTS && MAX_NUMBER_OF_CHART_OBJECTS > 1) { ArrayList copy = new ArrayList(); ArrayList others = new ArrayList(); double valueOfOthers = 0; for (int i = 0; i < plotItems.size(); i++) { if (i < MAX_NUMBER_OF_CHART_OBJECTS - 1) { PlotComparisonItem item = plotItems.get(i); item.setColor(this.getColor(i)); copy.add(plotItems.get(i)); } else { PlotComparisonItem item = plotItems.get(i); others.add(item); valueOfOthers += item.getValue2(); } } PlotComparisonItem otherItem = new PlotComparisonItem(OTHER_CHART_TITLE, this.getOtherColor(), 0., valueOfOthers); otherItem.setOtherData(others); copy.add(otherItem); Collections.sort(copy, new Comparator() { @Override public int compare(PlotComparisonItem s1, PlotComparisonItem s2) { return s2.getValue2().compareTo(s1.getValue2()); } }); return copy; } } return plotItems; } /* * FILTER STUFF */ private String getCurrentSelectedProtocol() { ArrayList protocolTitles = this.getSelectedProtocolTitles(); if (protocolTitles != null && protocolTitles.size() != 0) { return protocolTitles.get(0); } return this.protocolTitles().get(0); } public ArrayList protocolTitles() { ArrayList titles = new ArrayList(); for (String protocol : this.getResources().getStringArray(R.array.protocols)) { titles.add(protocol); } return titles; } public boolean[] selectedProtocols() { ArrayList protocols = this.protocolTitles(); boolean[] selected = new boolean[protocols.size()]; int i = 0; for (String protocol : protocols) { selected[i] = (this.filter.protocols.contains(protocol)); i++; } return selected; } public ArrayList getSelectedProtocolTitles() { ArrayList knownProtocols = this.protocolTitles(); if (this.filter.hasProtocols()) { ArrayList titles = new ArrayList(); int i = 0; for (boolean b : this.selectedProtocols()) { if (b) { String title = knownProtocols.get(i); titles.add(title); } i++; } return titles; } return this.protocolTitles(); } /* * * COLOR STUFF */ public int getOtherColor() { return Color.argb(255, 80, 80, 80); // grey } public Integer getColor(int index) { return ColorSequenceGenerator.getColorForIndex(index); } public LinearLayout getPlotLayout() { if (this.rootView != null) { return (LinearLayout) this.rootView.findViewById(R.id.plot_layout); } else { return null; } } /** * * FILTER STUFF * * */ private boolean isFilterSetForTitle(String title) { if (title.equals(FILTER_MENU_TITLE_BSSID)) { return this.filter.hasBSSIDs(); } if (title.equals(FILTER_MENU_TITLE_ESSID)) { return this.filter.hasESSIDs(); } if (title.equals(FILTER_MENU_TITLE_PROTOCOLS)) { return (this.filter.getProtocols() != null && this.filter.hasProtocols() && this.filter.getProtocols().size() != this.protocolTitles().size()); } if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_BELOW)) { return this.filter.hasBelowTimestamp(); } if (title.equals(FILTER_MENU_TITLE_TIMESTAMP_ABOVE)) { return this.filter.hasAboveTimestamp(); } return false; } private void clearFilter() { if (filter == null) this.filter = new LogFilter(); this.filter.clear(); } /* * * DATE TRANSFORMATION */ public long getDayHourFromDate(long timeInMillis) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timeInMillis); int hour = calendar.get(Calendar.HOUR_OF_DAY); int min = calendar.get(Calendar.MINUTE); return hour; } public long getDateFromMilliseconds(long timeInMillis) { long millisInDay = 60 * 60 * 24 * 1000; return (timeInMillis / millisInDay) * millisInDay; } /* * * */ private String getHourAsTimeString(long hour) { return "" + hour + ":00"; } static final DateFormat dateFormat = new SimpleDateFormat("d.M.yyyy"); @SuppressLint("SimpleDateFormat") private String getDateAsDayString(long timeStamp) { try { Date netDate = (new Date(timeStamp)); return dateFormat.format(netDate); } catch (Exception ex) { return "xx"; } } @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 */ private void userTappedOnLegendItem(int index) { if (index < this.currentData.size()) { PlotComparisonItem item = this.currentData.get(index); ArrayList selectedData; String sortKey = null; selectedData = new ArrayList(); if (item.getOtherData() == null) { selectedData.add(item.getTitle()); } else { for (PlotComparisonItem other : item.getOtherData()) { selectedData.add(other.getTitle()); } } LogFilter filter = new LogFilter(); if (this.currentPlotView instanceof PieGraph) { filter.setProtocols(selectedData); } if (this.currentPlotView instanceof BarGraph) { if (this.selectedCompareData.equals(COMPARE_TITLE_AttacksPerESSID)) { filter.setESSIDs(selectedData); sortKey = "ESSID"; } else { filter.setBSSIDs(selectedData); sortKey = "BSSID"; } ArrayList currentSelectedProtocol = new ArrayList(); currentSelectedProtocol.add(this.getCurrentSelectedProtocol()); filter.setProtocols(currentSelectedProtocol); } if (this.currentPlotView instanceof LineGraph) { selectedData = new ArrayList(); selectedData.add(item.getTitle()); filter.setESSIDs(selectedData); filter.setProtocols(this.filter.getProtocols()); sortKey = "ESSID"; } if (this.filter.hasATimestamp()) { filter.setAboveTimestamp(this.filter.getAboveTimestamp()); filter.setBelowTimestamp(this.filter.getBelowTimestamp()); } this.pushRecordOverviewForFilter(filter, sortKey); } } public void onSliceClick(int index) { } public void onBarClick(int index) { this.userTappedOnLegendItem(index); } private void pushRecordOverviewForFilter(LogFilter filter, String sortKey) { FragmentManager fm = this.getActivity().getFragmentManager(); if (fm != null) { RecordOverviewFragment newFragment = new RecordOverviewFragment(); newFragment.setUpNavigatible(true); newFragment.setFilter(filter); if (sortKey != null && sortKey.length() != 0) newFragment.setGroupKey(sortKey); MainActivity.getInstance().injectFragment(newFragment); } } }