Browse Source

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/scm-ssi-student-hostagev2

Alexander Brakowski 10 years ago
parent
commit
b20b156dc4

+ 43 - 6
src/de/tudarmstadt/informatik/hostage/ui2/fragment/RecordOverviewFragment.java

@@ -69,6 +69,8 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 
     UglyDbHelper dbh;
 
+    private String sectionToOpen = "";
+
 
     public RecordOverviewFragment(){}
 
@@ -182,6 +184,15 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 		//return super.onOptionsItemSelected(item);
 	}
 
+
+
+
+    public void onStart() {
+        super.onStart();
+        //this.populateListViewFromDB(this.expListView);
+        this.setSectionToOpen(this.sectionToOpen);
+    }
+
 	/*****************************
 	 *
 	 * 			Public API
@@ -193,9 +204,14 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 	 *
 	 * @param SSID the SSID
 	 */
-	public void showDetailsForSSID(String SSID) {
+	public void showDetailsForSSID(Context context,  String SSID) {
 		Log.e("RecordOverviewFragment", "Implement showDetailsForSSID!!");
-	}
+        this.clearFilter();
+        int ESSID_INDEX = 2;
+        ArrayList<String> ssids = new ArrayList<String>();
+        this.sectionToOpen = SSID;
+        this.groupingKey = this.groupingTitles(context).get(ESSID_INDEX);
+  	}
 
 
 	/*****************************
@@ -258,6 +274,17 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
         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();
 	}
@@ -482,6 +509,14 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
     	this.filter.clear();
 	}
 
+    public ArrayList<String> groupingTitles(Context context){
+        ArrayList<String> titles = new ArrayList<String>();
+        for (String groupTitle : context.getResources().getStringArray(
+                R.array.Grouping)) {
+            titles.add(groupTitle);
+        }
+        return titles;
+    }
     public ArrayList<String> groupingTitles(){
         ArrayList<String> titles = new ArrayList<String>();
         for (String groupTitle : this.getResources().getStringArray(
@@ -678,15 +713,17 @@ public class RecordOverviewFragment extends Fragment implements ChecklistDialog.
 
 		LatLng tudarmstadtLoc = new LatLng(49.86923, 8.6632768);
 
-		final int numSSIDs = 30;
+		final int numSSIDs = 10;
+		final int numUniqueSSIDs = 6;
 		final double ssidRadius = 0.1;
 		final double bssidRadius = 0.004;
-		int id = 0;
+		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;
-			int numBSSIDs = (random.nextInt() % 10) + 10;
+			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);

+ 12 - 7
src/de/tudarmstadt/informatik/hostage/ui2/fragment/StatisticsFragment.java

@@ -962,16 +962,21 @@ public class StatisticsFragment extends Fragment implements ChecklistDialog.Chec
     }
 
     public Integer generateColorForIndex(int index){
-        int r[] = new int[]{0,0,0,1,1,1,1};
-        int g[] = new int[]{0,1,1,1,1,0,0};
-        int b[] = new int[]{1,1,0,0,1,1,0};
+        int r[] = new int[]{0,0,1,1,0,1,1};
+        int g[] = new int[]{0,1,0,0,1,1,1};
+        int b[] = new int[]{1,0,0,1,1,0,1};
 
-        int a = index % 16;
+        int a = (index / 7);
         int n = index % 7;
 
-        int R = Math.max( (r[n] * 255) - ((Math.max(0,(a ))) * 16), 0);
-        int G = Math.max( (g[n] * 255) - ((Math.max(0,(a ))) * 16), 0);
-        int B = Math.max( (b[n] * 255) - ((Math.max(0,(a ))) * 16), 0);
+        int q = Math.max(1, 2 * (a / 7));
+        int multiplier = 16 / (q);
+
+        int sub = (Math.min(((Math.max(0,(a ))) * multiplier), 16));
+
+        int R = Math.max( (r[n] * 255) - sub, 0);
+        int G = Math.max( (g[n] * 255) - sub, 0);
+        int B = Math.max( (b[n] * 255) - sub, 0);
 
         return Color.argb(255,R,G,B);
     }

+ 190 - 51
src/de/tudarmstadt/informatik/hostage/ui2/fragment/ThreatMapFragment.java

@@ -4,13 +4,16 @@ import android.app.Fragment;
 import android.graphics.Color;
 import android.location.Location;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
 import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.GooglePlayServicesClient;
+import com.google.android.gms.location.LocationClient;
+import com.google.android.gms.location.LocationListener;
+import com.google.android.gms.location.LocationRequest;
 import com.google.android.gms.maps.CameraUpdateFactory;
 import com.google.android.gms.maps.GoogleMap;
 import com.google.android.gms.maps.MapFragment;
@@ -31,11 +34,25 @@ import de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity;
 import static com.google.android.gms.common.GooglePlayServicesUtil.*;
 
 /**
+ * ThreatMapFragment
+ *
  * Created by Fabio Arnold on 10.02.14.
  */
-public class ThreatMapFragment extends Fragment implements GoogleMap.OnInfoWindowClickListener {
-	private GoogleMap map = null;
-	private static View view = null;
+public class ThreatMapFragment extends Fragment implements GoogleMap.OnInfoWindowClickListener,
+		GooglePlayServicesClient.ConnectionCallbacks,
+		GooglePlayServicesClient.OnConnectionFailedListener,
+		LocationListener {
+	private static GoogleMap sMap = null;
+	private static View sView = null;
+
+	private static HashMap<String, String> sMarkerIDToSSID = new HashMap<String, String>();
+
+	private LocationClient mLocationClient;
+	private static final LocationRequest REQUEST = LocationRequest.create()
+			.setExpirationDuration(5000) // 5 seconds
+			.setInterval(5000)           // 5 seconds
+			.setFastestInterval(16)      // 16ms = 60fps
+			.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
 
 	/**
 	 * if google play services aren't available an error notification will be displayed
@@ -51,14 +68,50 @@ public class ThreatMapFragment extends Fragment implements GoogleMap.OnInfoWindo
 		return result;
 	}
 
+	/**
+	 * callback for when the info window of a marker gets clicked
+	 * open the RecordOverviewFragment and display all records belonging to an SSID
+	 *
+	 * @param marker this info window belongs to
+	 */
 	@Override
 	public void onInfoWindowClick(Marker marker) {
 		MainActivity.getInstance().displayView(MainActivity.MainMenuItem.RECORDS.getValue());
 		RecordOverviewFragment recordOverviewFragment = (RecordOverviewFragment)MainActivity.getInstance().getCurrentFragment();
-		recordOverviewFragment.showDetailsForSSID(marker.getId());
-		Log.i("MARKER", ""+marker.getId());
+		if (recordOverviewFragment != null) {
+			String ssid = sMarkerIDToSSID.get(marker.getId());
+			recordOverviewFragment.showDetailsForSSID(getActivity(), ssid);
+		}
+	}
+
+	/**
+	 * callbacks from LocationClient
+	 */
+	@Override
+	public void onConnected(Bundle bundle) {
+		mLocationClient.requestLocationUpdates(REQUEST, this);
+	}
+
+	@Override
+	public void onDisconnected() {
+
 	}
 
+	@Override
+	public void onConnectionFailed(ConnectionResult connectionResult) {
+
+	}
+
+	@Override
+	public void onLocationChanged(Location location) {
+		sMap.animateCamera(CameraUpdateFactory.newLatLng(
+				new LatLng(location.getLatitude(), location.getLongitude())));
+	}
+
+	/**
+	 * helper class
+	 * easier to use than LatLng
+	 */
 	private class Point {
 		public double x, y;
 		public Point(double sx, double sy) {
@@ -67,86 +120,172 @@ public class ThreatMapFragment extends Fragment implements GoogleMap.OnInfoWindo
 		}
 	}
 
+	/**
+	 * helper class
+	 * contains heuristic to split SSIDs by location
+	 * see MAX_DISTANCE
+	 */
+	private class SSIDArea {
+		private Point mMinimum, mMaximum;
+		public int numPoints;
+
+		public static final int MAX_NUM_ATTACKS = 20;
+		public static final float MAX_DISTANCE = 1000.0f; // 1km
+
+		public SSIDArea(LatLng initialLocation) {
+			//mMinimum = new Point(360.0, 360.0);
+			//mMaximum = new Point(-360.0, -360.0);
+			mMinimum = new Point(initialLocation.latitude, initialLocation.longitude);
+			mMaximum = new Point(initialLocation.latitude, initialLocation.longitude);
+			numPoints = 1;
+		}
+
+		public boolean doesLocationBelongToArea(LatLng location) {
+			LatLng center = calculateCenterLocation();
+			float[] result = new float[1];
+			Location.distanceBetween(center.latitude, center.longitude, location.latitude, location.longitude, result);
+			return result[0] < MAX_DISTANCE;
+		}
+
+		public void addLocation(LatLng location) {
+			Point point = new Point(location.latitude, location.longitude);
+			if (point.x < mMinimum.x) mMinimum.x = point.x;
+			if (point.x > mMaximum.x) mMaximum.x = point.x;
+			if (point.y < mMinimum.y) mMinimum.y = point.y;
+			if (point.y > mMaximum.y) mMaximum.y = point.y;
+			numPoints++;
+		}
+
+		public LatLng calculateCenterLocation() {
+			return new LatLng(0.5 * (mMinimum.x + mMaximum.x), 0.5 * (mMinimum.y + mMaximum.y));
+		}
+
+		public float calculateRadius() {
+			float[] result = new float[1];
+			Location.distanceBetween(mMinimum.x, mMinimum.y, mMaximum.x, mMaximum.y, result);
+			return 0.5f * result[0];
+		}
+
+		public int calculateColor() {
+			int threatLevel = numPoints;
+			if (threatLevel > MAX_NUM_ATTACKS) threatLevel = MAX_NUM_ATTACKS;
+			float alpha = 1.0f - (float)(threatLevel-1) / (float)(MAX_NUM_ATTACKS-1);
+			return Color.argb(127, (int) (240.0 + 15.0 * alpha), (int) (80.0 + 175.0 * alpha), 60);
+		}
+	}
+
+	/**
+	 * fills the map with markers and circle representing SSIDs
+	 */
 	private void populateMap() {
 		UglyDbHelper dbh = new UglyDbHelper(getActivity());
 		ArrayList<Record> records = dbh.getAllRecords();
 
-		HashMap<String, ArrayList<Point>> threatLocations = new HashMap<String, ArrayList<Point>>();
+		HashMap<String, ArrayList<SSIDArea>> threadAreas = new HashMap<String, ArrayList<SSIDArea>>();
 
 		for (Record record : records) {
 			LatLng location = new LatLng(record.getLatitude(), record.getLongitude());
-			ArrayList<Point> points;
-			if (threatLocations.containsKey(record.getSsid())) {
-				points = threatLocations.get(record.getSsid());
+			ArrayList<SSIDArea> areas;
+			if (threadAreas.containsKey(record.getSsid())) {
+				areas = threadAreas.get(record.getSsid());
+				boolean foundArea = false;
+				for (SSIDArea area : areas) {
+					if (area.doesLocationBelongToArea(location)) {
+						area.addLocation(location);
+						foundArea = true;
+						break;
+					}
+				}
+				if (!foundArea) {
+					areas.add(new SSIDArea(location));
+				}
 			} else {
-				points = new ArrayList<Point>();
-				threatLocations.put(record.getSsid(), points);
+				areas = new ArrayList<SSIDArea>();
+				areas.add(new SSIDArea(location));
+				threadAreas.put(record.getSsid(), areas);
 			}
-			points.add(new Point(location.latitude, location.longitude));
 		}
 
-		final int maxNumAttacks = 20;
 		CircleOptions circleOptions = new CircleOptions().radius(200.0).fillColor(Color.argb(127, 240, 80, 60)).strokeWidth(0.0f);
-		for (Map.Entry<String, ArrayList<Point>> entry : threatLocations.entrySet()) {
+		for (Map.Entry<String, ArrayList<SSIDArea>> entry : threadAreas.entrySet()) {
 			String ssid = entry.getKey();
-			ArrayList<Point> points = entry.getValue();
-
-			// color
-			int threatLevel = points.size();
-			if (threatLevel > maxNumAttacks) threatLevel = maxNumAttacks;
-			float alpha = 1.0f - (float)(threatLevel-1) / (float)(maxNumAttacks-1);
-			int color = Color.argb(127, (int) (240.0 + 15.0 * alpha), (int) (80.0 + 175.0 * alpha), 60);
-
-			// radius
-			Point minimum = new Point(360.0, 360.0), maximum = new Point(-360.0, -360.0);
-			for (Point point : points) {
-				if (point.x < minimum.x) minimum.x = point.x;
-				if (point.x > maximum.x) maximum.x = point.x;
-				if (point.y < minimum.y) minimum.y = point.y;
-				if (point.y > maximum.y) maximum.y = point.y;
+			ArrayList<SSIDArea> areas = entry.getValue();
+
+			for (SSIDArea area : areas) {
+				int color = area.calculateColor();
+				LatLng center = area.calculateCenterLocation();
+				float radius = area.calculateRadius();
+
+				sMap.addCircle(circleOptions.center(center).radius(100.0 + radius).fillColor(color));
+				Marker marker = sMap.addMarker(new MarkerOptions()
+						.title(ssid + ": " + area.numPoints + (area.numPoints == 1 ? " attack"
+								: " attacks")).position(
+								center));
+
+				sMarkerIDToSSID.put(marker.getId(), ssid);
 			}
-			LatLng center = new LatLng(0.5 * (minimum.x + maximum.x), 0.5 * (minimum.y + maximum.y));
-			float[] result = new float[1];
-			Location.distanceBetween(minimum.x, minimum.y, maximum.x, maximum.y, result);
-			float radius = 0.5f * result[0];
-			map.addCircle(circleOptions.center(center).radius(100.0 + radius).fillColor(color));
-			map.addMarker(new MarkerOptions().title(ssid + ": " + points.size() + (points.size() == 1 ? " attack" : " attacks")).position(
-					center));
 		}
 
-		map.setMyLocationEnabled(true);
-		map.setOnInfoWindowClickListener(this);
+		sMap.setMyLocationEnabled(true);
 
-		LatLng tudarmstadt = new LatLng(49.86923, 8.6632768);
-		//LatLng mapCenter = new LatLng(41.889, -87.622);
-
-		//Location myLocation = map.getMyLocation();
-		map.moveCamera(CameraUpdateFactory.newLatLngZoom(tudarmstadt, 13));
+		LatLng tudarmstadt = new LatLng(49.86923, 8.6632768); // default location
+		sMap.moveCamera(CameraUpdateFactory.newLatLngZoom(tudarmstadt, 13));
 	}
 
+	/**
+	 * performs initialization
+	 * checks if google play services are supported
+	 * view must be removed if this object has been created once before
+	 * that is why view is static
+	 *
+	 * @param inflater
+	 * @param container
+	 * @param savedInstanceState
+	 * @return the view
+	 */
 	@Override
 	public View onCreateView(LayoutInflater inflater, ViewGroup container,
 	                         Bundle savedInstanceState) {
 		super.onCreateView(inflater, container, savedInstanceState);
 
-		if (view != null) {
-			ViewGroup parent = (ViewGroup) view.getParent();
+		if (sView != null) {
+			ViewGroup parent = (ViewGroup) sView.getParent();
 			if (parent != null)
-				parent.removeView(view);
+				parent.removeView(sView);
 		}
 		
 		try {
-			view = inflater.inflate(R.layout.fragment_threatmap, container, false);
+			sView = inflater.inflate(R.layout.fragment_threatmap, container, false);
 			if (isGooglePlay()) {
-				map = ((MapFragment) getFragmentManager()
+				sMap = ((MapFragment) getFragmentManager()
 						.findFragmentById(R.id.threatmapfragment)).getMap();
 				populateMap();
 			}
 		} catch (InflateException e) {
         	// map already exists
-			e.printStackTrace();
+			//e.printStackTrace();
+		}
+		if (sMap != null) {
+			sMap.setOnInfoWindowClickListener(this);
 		}
 
-		return view;
+		return sView;
+	}
+
+	@Override
+	public void onResume() {
+		super.onResume();
+		if (mLocationClient == null) {
+			mLocationClient = new LocationClient(MainActivity.getInstance().getApplicationContext(), this, this);
+		}
+		mLocationClient.connect();
+	}
+
+	@Override
+	public void onPause() {
+		super.onPause();
+		if (mLocationClient != null) {
+			mLocationClient.disconnect();
+		}
 	}
 }