package de.tudarmstadt.informatik.hostage.ui2.fragment; import android.annotation.SuppressLint; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ExpandableListView; import android.widget.ImageButton; import com.google.android.gms.maps.model.LatLng; 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 java.util.Random; import de.tudarmstadt.informatik.hostage.R; import de.tudarmstadt.informatik.hostage.logging.Record; import de.tudarmstadt.informatik.hostage.logging.Record.TYPE; import de.tudarmstadt.informatik.hostage.logging.UglyDbHelper; import de.tudarmstadt.informatik.hostage.ui.LogFilter; import de.tudarmstadt.informatik.hostage.ui.LogFilter.SortType; import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity; import de.tudarmstadt.informatik.hostage.ui2.adapter.RecordListAdapter; import de.tudarmstadt.informatik.hostage.ui2.dialog.ChecklistDialog; import de.tudarmstadt.informatik.hostage.ui2.dialog.DateTimeDialogFragment; import de.tudarmstadt.informatik.hostage.ui2.fragment.interfaces.UpNavigatible; import de.tudarmstadt.informatik.hostage.ui2.model.ExpandableListItem; 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; public class RecordOverviewFragment extends Fragment implements ChecklistDialog.ChecklistDialogListener, DateTimeDialogFragment.DateTimeDialogFragmentListener, UpNavigatible { static final String SELECTED_KEY = "Selected"; static final String OTHERS_KEY = "Other"; 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"; private boolean wasBelowTimePicker; private LogFilter filter; private boolean showFilterButton; public String groupingKey; private ExpandableListView expListView; UglyDbHelper dbh; private String sectionToOpen = ""; public void setFilter(LogFilter filter){ this.filter = filter; } public RecordOverviewFragment(){} public void setGroupKey(String key){ this.groupingKey = key; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getActivity().setTitle(getResources().getString(R.string.drawer_records)); dbh = new UglyDbHelper(this.getActivity().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; } } if (this.groupingKey == null) this.groupingKey = this.groupingTitles().get(0); this.setShowFilterButton(!this.filter.isNotEditable()); this.addRecordToDB(); View rootView = inflater.inflate(this.getLayoutId(), container, false); ExpandableListView mylist = (ExpandableListView) rootView.findViewById(R.id.loglistview); this.expListView = mylist; populateListViewFromDB(mylist); registerListClickCallback(mylist); ImageButton filterButton = (ImageButton) rootView.findViewById(R.id.FilterButton); filterButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { RecordOverviewFragment.this.openFilterPopupMenuOnView(v); } }); filterButton.setVisibility(this.showFilterButton? View.VISIBLE : View.INVISIBLE); ImageButton sortButton = (ImageButton) rootView.findViewById(R.id.SortButton); sortButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Open SortMenu RecordOverviewFragment.this.openSortingDialog(); } }); ImageButton groupButton = (ImageButton) rootView.findViewById(R.id.GroupButton); groupButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Open SortMenu RecordOverviewFragment.this.openGroupingDialog(); } }); return rootView; } public int getLayoutId(){ return R.layout.fragment_record_list; } public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); } public void onFilterMenuItemSelected(AbstractPopupItem item) { String title = item.getTitle(); if (item instanceof SplitPopupItem){ SplitPopupItem splitItem = (SplitPopupItem)item; if (splitItem.wasRightTouch){ this.openTimestampToFilterDialog(); } else { this.openTimestampFromFilterDialog(); } return; } if (title != null){ if(title.equals(FILTER_MENU_TITLE_BSSID)){ this.openBSSIDFilterDialog(); } if(title.equals(FILTER_MENU_TITLE_ESSID)){ this.openESSIDFilterDialog(); } if(title.equals(FILTER_MENU_TITLE_PROTOCOLS)){ this.openProtocolsFilterDialog(); } if(title.equals(FILTER_MENU_TITLE_SORTING)){ this.openSortingDialog(); } if(title.equals(FILTER_MENU_TITLE_REMOVE)){ this.clearFilter(); this.populateListViewFromDB(this.expListView); } if(title.equals(FILTER_MENU_TITLE_TIMESTAMP_BELOW)){ this.openTimestampToFilterDialog(); } if(title.equals(FILTER_MENU_TITLE_TIMESTAMP_ABOVE)){ this.openTimestampFromFilterDialog(); } } //return super.onOptionsItemSelected(item); } public void onStart() { super.onStart(); //this.populateListViewFromDB(this.expListView); if (this.expListView.getExpandableListAdapter().getGroupCount() == 1){ this.expListView.expandGroup(0); } else { this.setSectionToOpen(this.sectionToOpen); } } /***************************** * * Public API * * ***************************/ /** * Group records by SSID and expand given SSID * * @param SSID the SSID */ public void showDetailsForSSID(Context context, String SSID) { Log.e("RecordOverviewFragment", "Implement showDetailsForSSID!!"); this.clearFilter(); int ESSID_INDEX = 2; ArrayList ssids = new ArrayList(); this.sectionToOpen = SSID; this.groupingKey = this.groupingTitles(context).get(ESSID_INDEX); } /***************************** * * ListView Stuff * * ***************************/ private void populateListViewFromDB(ExpandableListView mylist) { HashMap> sectionData = new HashMap>(); ArrayList data = dbh.getRecordsForFilter(this.filter); // Adding Items to ListView String keys[] = new String[] { this.getString(R.string.RecordBSSID), this.getString(R.string.RecordSSID), this.getString(R.string.RecordProtocol), this.getString(R.string.RecordTimestamp)}; int ids[] = new int[] {R.id.RecordTextFieldBSSID, R.id.RecordTextFieldSSID, R.id.RecordTextFieldProtocol, R.id.RecordTextFieldTimestamp }; HashMap mapping = new HashMap(); int i = 0; for(String key : keys){ mapping.put(key, ids[i]); i++; } ArrayListgroupTitle = new ArrayList(); for (Record val : data) { // DO GROUPING IN HERE HashMap map = new HashMap(); map.put(this.getString(R.string.RecordBSSID), val.getBssid()); map.put(this.getString(R.string.RecordSSID), val.getSsid()); map.put(this.getString(R.string.RecordProtocol), val.getProtocol()); map.put(this.getString(R.string.RecordTimestamp), this.getDateAsString(val.getTimestamp())); ExpandableListItem item = new ExpandableListItem(); item.setData(map); item.setId_Mapping(mapping); item.setTag(val.getId()); String groupID = this.getGroupValue(val); ArrayList items = sectionData.get(groupID); if (items == null) { items = new ArrayList(); sectionData.put(groupID, items); groupTitle.add(groupID); } items.add(item); } Collections.sort(groupTitle, new Comparator() { @Override public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); } }); RecordListAdapter adapter = new RecordListAdapter(this.getApplicationContext(), groupTitle, sectionData); mylist.setAdapter(adapter); } private void setSectionToOpen(String s){ this.sectionToOpen = s; if (this.sectionToOpen != null && this.sectionToOpen.length() != 0){ if (this.getGroupTitle().contains(this.sectionToOpen)){ int section = this.getGroupTitle().indexOf(this.sectionToOpen); this.expListView.expandGroup(section); this.sectionToOpen = ""; } } } private Context getBaseContext(){ return this.getActivity().getBaseContext(); } private Context getApplicationContext(){ return this.getActivity().getApplicationContext(); } private void registerListClickCallback(ExpandableListView mylist) { mylist.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i2, long l) { RecordListAdapter adapter = (RecordListAdapter)expandableListView.getExpandableListAdapter(); ExpandableListItem item = (ExpandableListItem)adapter.getChild(i,i2); UglyDbHelper dbh = new UglyDbHelper(getBaseContext()); Record rec = dbh.getRecord((int) item.getTag()); RecordOverviewFragment.this.pushRecordDetailViewForRecord(rec); return true; } }); } /***************************** * * Date Transform * * ***************************/ @SuppressLint("SimpleDateFormat") private String getDateAsString(long timeStamp) { try { DateFormat sdf = new SimpleDateFormat("H:mm d.M.yy"); Date netDate = (new Date(timeStamp)); return sdf.format(netDate); } catch (Exception ex) { return "xx"; } } /***************************** * * Getter / Setter * * ***************************/ public boolean isShowFilterButton() { return showFilterButton; } public void setShowFilterButton(boolean showFilterButton) { this.showFilterButton = showFilterButton; } /***************************** * * Open Dialog Methods * * ***************************/ private void openGroupingDialog(){ ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_GROUP, this.groupingTitles(), this.selectedGroup(), false , this); newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_GROUP); } 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 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 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 openTimestampFromFilterDialog(){ this.wasBelowTimePicker = false; DateTimeDialogFragment newFragment = new DateTimeDialogFragment(this.getActivity()); newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_SORTING); 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.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_SORTING); if (this.filter.belowTimestamp != Long.MAX_VALUE) newFragment.setDate(this.filter.belowTimestamp); } private void openSortingDialog(){ ChecklistDialog newFragment = new ChecklistDialog(FILTER_MENU_TITLE_SORTING,this.sortTypeTiles(), this.selectedSorttype(), false , this); newFragment.show(this.getActivity().getFragmentManager(), FILTER_MENU_TITLE_SORTING); } /***************************** * * Grouping Stuff * * ***************************/ public String getGroupValue(Record rec){ int index = this.groupingTitles().indexOf(this.groupingKey); switch (index){ case 0: return rec.getProtocol(); case 1: return rec.getBssid(); case 2: return rec.getSsid(); default: return rec.getProtocol(); } } public ArrayList getGroupTitle(){ int index = this.groupingTitles().indexOf(this.groupingKey); switch (index){ case 0: return this.protocolTitles(); case 1: return this.bssids(); case 2: return this.essids(); default: return this.protocolTitles(); } } /***************************** * * Filter Stuff * * ***************************/ private void openFilterPopupMenuOnView(View v){ SimplePopupTable filterMenu = new SimplePopupTable(this.getActivity(), new AbstractPopup.OnPopupItemClickListener() { public void onItemClick(Object ob) { if (ob instanceof AbstractPopupItem){ AbstractPopupItem item = (AbstractPopupItem) ob; RecordOverviewFragment.this.onFilterMenuItemSelected(item); } } }); filterMenu.setTitle(FILTER_MENU_POPUP_TITLE); for(String title : RecordOverviewFragment.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(v); } 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.hasProtocols(); } 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(); } public ArrayList groupingTitles(Context context){ ArrayList titles = new ArrayList(); for (String groupTitle : context.getResources().getStringArray( R.array.Grouping)) { titles.add(groupTitle); } return titles; } public ArrayList groupingTitles(){ ArrayList titles = new ArrayList(); for (String groupTitle : this.getResources().getStringArray( R.array.Grouping)) { titles.add(groupTitle); } return titles; } public boolean[] selectedGroup(){ ArrayList groups = this.groupingTitles(); boolean[] selected = new boolean[groups.size()]; int i = 0; for(String group : groups){ selected[i] =(group.equals(this.groupingKey)); i++; } return selected; } 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 sortTypeTiles(){ ArrayList titles = new ArrayList(); titles.add("Time"); titles.add("Protocol"); titles.add("BSSID"); titles.add("ESSID"); //titles.add("Remote Host Name"); //titles.add("Local Host Name"); //titles.add("Attack ID"); //titles.add("ID"); return titles; } public boolean[] selectedSorttype(){ ArrayList types = this.sortTypeTiles(); boolean[] selected = new boolean[types.size()]; int i = 0; for(String sorttype : types){ selected[i] =(this.filter.sorttype.toString().equals(sorttype)); i++; } return selected; } public ArrayList bssids(){ ArrayList 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.BSSIDs.contains(bssid)); i++; } return selected; } public ArrayList essids(){ ArrayList 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.ESSIDs.contains(essid)); i++; } return selected; } private ArrayList filterMenuTitles(){ ArrayList titles = new ArrayList(); titles.add(FILTER_MENU_TITLE_BSSID); titles.add(FILTER_MENU_TITLE_ESSID); titles.add(FILTER_MENU_TITLE_PROTOCOLS); titles.add(FILTER_MENU_TITLE_TIMESTAMP_ABOVE); titles.add(FILTER_MENU_TITLE_TIMESTAMP_BELOW); if (this.filter.isSet())titles.add(FILTER_MENU_TITLE_REMOVE); return titles; } /***************************** * * Listener Actions * * ***************************/ public void onDateTimePickerPositiveClick(DateTimeDialogFragment dialog) { if(this.wasBelowTimePicker){ this.filter.setBelowTimestamp(dialog.getDate()); } else { this.filter.setAboveTimestamp(dialog.getDate()); } this.populateListViewFromDB(this.expListView); } public void onDateTimePickerNegativeClick(DateTimeDialogFragment dialog) { if(this.wasBelowTimePicker){ this.filter.setBelowTimestamp(Long.MAX_VALUE); } else { this.filter.setAboveTimestamp(Long.MIN_VALUE); } } public void onDialogPositiveClick(ChecklistDialog dialog) { String title = dialog.getTitle(); if(title.equals(FILTER_MENU_TITLE_BSSID)){ ArrayList titles =dialog.getSelectedItemTitles(); if (titles.size() == this.bssids().size()){ this.filter.setBSSIDs(new ArrayList()); } else { this.filter.setBSSIDs(titles); } } if(title.equals(FILTER_MENU_TITLE_ESSID)){ ArrayList titles =dialog.getSelectedItemTitles(); if (titles.size() == this.essids().size()){ this.filter.setESSIDs(new ArrayList()); } else { this.filter.setESSIDs(titles); } } if(title.equals(FILTER_MENU_TITLE_PROTOCOLS)){ ArrayList protocols = dialog.getSelectedItemTitles(); if (protocols.size() == this.protocolTitles().size()){ this.filter.setProtocols(new ArrayList()); } else { this.filter.setProtocols(dialog.getSelectedItemTitles()); } } if(title.equals(FILTER_MENU_TITLE_SORTING)){ ArrayList titles = dialog.getSelectedItemTitles(); if (titles.size() == 0) return; String t = titles.get(0); int sortType = this.sortTypeTiles().indexOf(t); this.filter.setSorttype(SortType.values()[sortType]); } if (title.equals(FILTER_MENU_TITLE_GROUP)){ ArrayList titles = dialog.getSelectedItemTitles(); if (titles.size() == 0) return; this.groupingKey = titles.get(0); } this.populateListViewFromDB(this.expListView); } public void onDialogNegativeClick(ChecklistDialog dialog) { } /***************************** * * TEST * * ***************************/ private void addRecordToDB() { if ((dbh.getRecordCount() > 0)) return; Calendar cal = Calendar.getInstance(); int maxProtocolsIndex = this.getResources().getStringArray( R.array.protocols).length; Random random = new Random(); LatLng tudarmstadtLoc = new LatLng(49.86923, 8.6632768); final int numSSIDs = 10; final int numUniqueSSIDs = 6; final double ssidRadius = 0.1; final double bssidRadius = 0.004; int id = 0; // global id for (int ssid = 0; ssid < numSSIDs; ssid++) { LatLng ssidLocation = new LatLng(tudarmstadtLoc.latitude - ssidRadius + 2.0 * ssidRadius * Math.random(), tudarmstadtLoc.longitude - ssidRadius + 2.0 * ssidRadius * Math.random()); String ssidName = "WiFi" + ((ssid % numUniqueSSIDs) + 1); int numBSSIDs = (Math.abs(random.nextInt()) % 20) + 1; for (int bssid = 0; bssid < numBSSIDs; bssid++) { Record record = new Record(); record.setId(id); record.setAttack_id(id); record.setBssid("BSSID" + id); id++; record.setSsid(ssidName); record.setTimestamp(cal.getTimeInMillis() + ((id * 60 * 60 * 60 * 24) * 1000)); int index = id % maxProtocolsIndex; String protocolName = this.getResources().getStringArray( R.array.protocols)[index]; record.setProtocol(protocolName); record.setLocalIP("127.0.0.1"); record.setType(TYPE.SEND); record.setLatitude( ssidLocation.latitude - bssidRadius + 2.0 * bssidRadius * Math.random()); record.setLongitude(ssidLocation.longitude - bssidRadius + 2.0 * bssidRadius * Math.random()); dbh.addRecord(record); } } int countAllLogs = dbh.getAllRecords().size(); int countRecords = dbh.getRecordCount(); int countAttacks = dbh.getAttackCount(); if ((countRecords == 0)) { Record rec = dbh.getRecordOfAttackId(0); Record rec2 = dbh.getRecord(0); System.out.println("" + "Could not create logs!"); } } /*Navigation*/ private void pushRecordDetailViewForRecord(Record record){ FragmentManager fm = this.getActivity().getFragmentManager(); if (fm != null){ RecordDetailFragment newFragment = new RecordDetailFragment(); newFragment.setRecord(record); MainActivity.getInstance().injectFragment(newFragment, true); } } private Class upFragment; private boolean isUpNavigatible = false; @Override public Class getUpFragment() { return upFragment; } @Override public void setUpFragment( Class upFragment) { this.upFragment = upFragment; } @Override public boolean isUpNavigatible() { return isUpNavigatible; } @Override public void setUpNavigatible(boolean isUpNavigatible) { this.isUpNavigatible = isUpNavigatible; } }