Browse Source

solved merge conflicts

Daniel Lazar 7 years ago
parent
commit
f25139dc2b
26 changed files with 367 additions and 160 deletions
  1. 1 1
      AndroidManifest.xml
  2. 1 1
      build.gradle
  3. BIN
      docs/sync/hostage_sync_uml.png
  4. 19 0
      docs/sync/hostage_sync_uml_desc.txt
  5. 7 11
      res/layout/fragment_about.xml
  6. 31 11
      res/layout/fragment_record_detail.xml
  7. 9 0
      res/layout/fragment_record_list.xml
  8. 1 1
      res/values-de/arrays.xml
  9. 30 2
      res/values-de/strings.xml
  10. 2 2
      res/values/arrays.xml
  11. 4 3
      res/values/strings.xml
  12. 2 0
      res/values/strings_preferences.xml
  13. 4 2
      res/xml/settings_preferences.xml
  14. 6 4
      src/de/tudarmstadt/informatik/hostage/Listener.java
  15. 29 5
      src/de/tudarmstadt/informatik/hostage/persistence/HostageDBOpenHelper.java
  16. 9 9
      src/de/tudarmstadt/informatik/hostage/sync/android/SyncUtils.java
  17. 6 6
      src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pBroadcastReceiver.java
  18. 8 8
      src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pClientTask.java
  19. 6 6
      src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pServerTask.java
  20. 13 13
      src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/ui/WiFiP2pSyncActivity.java
  21. 39 37
      src/de/tudarmstadt/informatik/hostage/ui/fragment/HomeFragment.java
  22. 10 17
      src/de/tudarmstadt/informatik/hostage/ui/fragment/PreferenceHostageFragment.java
  23. 10 7
      src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordDetailFragment.java
  24. 74 9
      src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordOverviewFragment.java
  25. 5 3
      src/de/tudarmstadt/informatik/hostage/ui/fragment/ServicesFragment.java
  26. 41 2
      src/de/tudarmstadt/informatik/hostage/ui/fragment/ThreatMapFragment.java

+ 1 - 1
AndroidManifest.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="de.tudarmstadt.informatik.hostage"
-    android:versionCode="2"
+    android:versionCode="3"
     android:versionName="1.1" >
 
     <uses-sdk

+ 1 - 1
build.gradle

@@ -35,7 +35,7 @@ android {
 
     defaultConfig {
         versionCode 2
-        versionName "2.0"
+        versionName "3.0"
         minSdkVersion 14
         targetSdkVersion 19
     }

BIN
docs/sync/hostage_sync_uml.png


+ 19 - 0
docs/sync/hostage_sync_uml_desc.txt

@@ -0,0 +1,19 @@
+title Synchronisation Protocol
+
+DeviceA->+DeviceB: Send Sync Info
+note right of DeviceB: The Sync Info is a tuple (otherDevices, ssids) where\notherDevices ∈ ℘(DeviceIds x ℕ)\nand ssids ∈ ℘(NetworkSSIDs)
+
+
+DeviceB->-DeviceA: Send Sync Info
+note right of DeviceB: Compare own Sync Info with the other\nSync Info to create a Sync Data object.
+
+
+note over DeviceA,DeviceB: If we received unknown Device Ids create new Sync Devices.\nSet the max sync id for each new device to 0.
+
+
+DeviceA->+DeviceB: Send Sync Data
+note right of DeviceB: Sync Data is a tuple (n , a) where\nn ∈ ℘(NetworkRecords) and a ∈ ℘(AttackRecords)
+DeviceB->-DeviceA: Send Sync Data
+
+
+note over DeviceA,DeviceB: Save received network and attack records.\nActualise the max sync id if of all Sync Devices.

+ 7 - 11
res/layout/fragment_about.xml

@@ -98,17 +98,13 @@
 		<LinearLayout
 				android:orientation="vertical"
 				android:layout_width="wrap_content"
-				android:layout_height="wrap_content" android:layout_weight="0.5"
-				android:id="@+id/linearLayout"
-				android:layout_alignParentTop="true" android:layout_alignParentRight="true"
-				android:layout_alignParentEnd="true" android:layout_marginRight="10dp">
-			<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
-			          android:textAppearance="?android:attr/textAppearanceMedium"
-			          android:text="@string/core_dev_by" android:id="@+id/record_details_text_remoteip"
-			          android:singleLine="false"
-			          android:autoText="false" android:layout_marginTop="8dp"
-			          android:textStyle="bold" android:textColor="@android:color/holo_blue_dark"
-			          android:layout_gravity="right"/>
+				android:layout_height="wrap_content"
+            android:id="@+id/linearLayout"
+            android:layout_alignParentBottom="false"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="false"
+            android:paddingTop="33dp">
+
 			<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
 			          android:textAppearance="?android:attr/textAppearanceMedium"
 			          android:text="Lars Pandikow" android:id="@+id/textView9"

+ 31 - 11
res/layout/fragment_record_detail.xml

@@ -1,10 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="match_parent"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="match_parent"
+    >
+<ScrollView android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:id="@+id/scrollView"
-            android:fillViewport="true">
+            android:fillViewport="true" android:layout_above="@+id/linearLayout">
 
 	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 				  android:orientation="vertical"
@@ -159,14 +162,31 @@
 				android:layout_marginTop="10dp"
 				android:layout_marginBottom="20dp"/>
 
-	</LinearLayout>
-
 
-		<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
-				android:text="@string/delete" android:id="@+id/record_delete_button"
-				android:layout_gravity="center_horizontal" android:layout_weight="0"
-				android:layout_margin="8dp" android:background="@color/holo_red"
-				android:textColor="@android:color/white"/>
+	</LinearLayout>
 
 	</LinearLayout>
-</ScrollView>
+</ScrollView>
+<RelativeLayout
+    style="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:alpha="0.8"
+    android:id="@+id/linearLayout"
+    android:layout_alignParentBottom="true" android:layout_alignParentLeft="true"
+    android:layout_alignParentStart="true">
+
+    <ImageButton
+        style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/DeleteButton"
+        android:src="@drawable/ic_action_discard"
+        android:layout_gravity="right"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_toLeftOf="@+id/FilterButton"/>
+
+</RelativeLayout>
+</RelativeLayout>

+ 9 - 0
res/layout/fragment_record_list.xml

@@ -64,6 +64,15 @@
             android:layout_alignParentTop="true"
             android:layout_toLeftOf="@+id/GroupButton"/>
 
+        <ImageButton
+            style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/DeleteButton"
+            android:src="@drawable/ic_action_discard"
+            android:layout_alignParentTop="true"
+            android:layout_toLeftOf="@+id/FilterButton"/>
+
         <ImageButton
             style="@android:style/Widget.DeviceDefault.ActionButton.Overflow"
             android:layout_width="wrap_content"

+ 1 - 1
res/values-de/arrays.xml

@@ -3,7 +3,7 @@
 
     <string-array name="format">
         <item>Standard</item>
-        <item>TraCINg JSON</item>
+        <item>JSON</item>
     </string-array>
 
     <string-array name="delete_criteria">

File diff suppressed because it is too large
+ 30 - 2
res/values-de/strings.xml


+ 2 - 2
res/values/arrays.xml

@@ -2,8 +2,8 @@
 <resources>
 
     <string-array name="format">
-        <item>DEFAULT</item>
-        <item>TraCINg JSON</item>
+        <item>Plaintext</item>
+        <item>JSON</item>
     </string-array>
     
     <string-array name="delete_criteria">

+ 4 - 3
res/values/strings.xml

@@ -76,7 +76,8 @@
 	<string name="delete_dialog_title">Delete data sets by:</string>	
 	<string name="dialog_clear_database_date">Delete all data before:</string>
 
-    <string name="deleteAttacksTitle">Delete the these attack entries?</string>
+    <string name="deleteFILTEREDAttacksTitle">Delete the filtered attack data?</string>
+    <string name="deleteALLAttacksTitle">Delete all attack data?\n\nYou can delete specific attack data by filtering!</string>
 
 	<string name="threatmap_show_records"><u>Show records</u></string>
 
@@ -97,7 +98,7 @@
     <string name="drawer_services">Services</string>
     <string name="drawer_settings">Settings</string>
     <string name="drawer_profile_manager">Profiles</string>
-    <string name="drawer_app_info">Application info</string>
+    <string name="drawer_app_info">About</string>
 	<string name="drawer_statistics">Statistics</string>
 	<string name="drawer_help">Help videos</string>
 
@@ -128,7 +129,7 @@
     <string name="hostage_with_url"><a href="http://www.tk.informatik.tu-darmstadt.de/de/research/secure-smart-infrastructures/hostage">HosTaGe</a></string>
     <string name="hostage_email"><a href="mailto:hostage@tk.informatik.tu-darmstadt.de?Subject=Inquiry">Tell us what do you think about HosTaGe</a></string>
     <string name="hostage_email_only">hostage@tk.informatik.tu-darmstadt.de</string>
-    <string name="ui_dev_by">UI developed by</string>
+    <string name="ui_dev_by">Developers team:</string>
     <string name="core_dev_by">Core developed by</string>
     <string name="advanced_settings">Advanced Settings</string>
     <string name="change_name_of_profile">Change the name of this profile</string>

+ 2 - 0
res/values/strings_preferences.xml

@@ -18,6 +18,7 @@
 	<string name="pref_connection_settings">Connection Settings</string>
 	<string name="pref_max_connections">Max Connections</string>	
 	<integer name="pref_max_connections_default">5</integer>
+	<string name="pref_max_connections_summary">Maximum simultaneous connections per protocol</string>
 	<string name="pref_timeout">Socket Timeout</string>
 	<string name="pref_timeout_summary">After this many seconds close socket when no communication occurred</string>
 	<integer name="pref_timeout_default">30</integer>
@@ -30,6 +31,7 @@
 	<string name="pref_location_time_default">60000</string>
 	<string name="pref_location_retries">Retries</string>
 	<string name="pref_location_retries_default">3</string>
+	<string name="pref_location_retries_summary">Maximum number of retries</string>
 	<string name="pref_auto_synchronize_title">Auto Synchronization</string>
 	<string name="pref_auto_synchronize_summ">Enable auto synchronization of log data</string>
 

+ 4 - 2
res/xml/settings_preferences.xml

@@ -54,7 +54,8 @@
 						android:numeric="decimal"
 						android:key="pref_max_connections"
 						android:defaultValue="@integer/pref_max_connections_default"
-						android:title="@string/pref_max_connections" />
+						android:title="@string/pref_max_connections"
+						android:summary="@string/pref_max_connections_summary" />
 
 				<EditTextPreference
 						android:inputType="number"
@@ -90,7 +91,8 @@
                 <EditTextPreference
                     android:key="pref_location_retries"
                     android:defaultValue="@string/pref_location_retries_default"
-                    android:title="@string/pref_location_retries" />
+                    android:title="@string/pref_location_retries"
+					android:summary="@string/pref_location_retries_summary" />
 
             </PreferenceCategory>
 		</PreferenceScreen>

+ 6 - 4
src/de/tudarmstadt/informatik/hostage/Listener.java

@@ -306,10 +306,6 @@ public class Listener implements Runnable {
 		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(service);
 		SharedPreferences connInfo = service.getSharedPreferences(service.getString(R.string.connection_info), Context.MODE_PRIVATE);
 
-		// only handler informs about attacks so its name is used here
-		service.notifyUI(Handler.class.getName(), new String[] {service.getString(R.string.broadcast_started), "PORTSCAN", Integer.toString(
-				client.getPort())});
-
 		AttackRecord attackRecord = new AttackRecord(true);
 
 		attackRecord.setProtocol("PORTSCAN");
@@ -335,5 +331,11 @@ public class Listener implements Runnable {
 			networkRecord.setTimestampLocation(0);
 		}
 		Logger.logPortscan(Hostage.getContext(), attackRecord, networkRecord, timestamp);
+
+		// now that the record exists we can inform the ui
+		// only handler informs about attacks so its name is used here
+		service.notifyUI(Handler.class.getName(),
+				new String[]{service.getString(R.string.broadcast_started), "PORTSCAN",
+						Integer.toString(client.getPort())});
 	}
 }

+ 29 - 5
src/de/tudarmstadt/informatik/hostage/persistence/HostageDBOpenHelper.java

@@ -538,7 +538,7 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 		return result > 0;
 	}
 	
-	public synchronized int numBssidSeen(String BSSID) {
+	public synchronized int getNumAttacksSeenByBSSID(String BSSID) {
 		String countQuery = "SELECT  COUNT(*) FROM " + AttackEntry.TABLE_NAME + " WHERE "
 				+ AttackEntry.TABLE_NAME + "." + AttackEntry.COLUMN_NAME_BSSID + " = " + "'" + BSSID + "'";
 		SQLiteDatabase db = this.getReadableDatabase();
@@ -550,7 +550,7 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
 		return result;
 	}
 
-    synchronized public int numBssidSeen(String protocol, String BSSID) {
+    synchronized public int getNumAttacksSeenByBSSID(String protocol, String BSSID) {
 		String countQuery = "SELECT  COUNT(*) FROM " + AttackEntry.TABLE_NAME 
 						+  " WHERE " + AttackEntry.TABLE_NAME + "." + AttackEntry.COLUMN_NAME_PROTOCOL + " = " + "'" + protocol + "'" 
 						+  " AND " + AttackEntry.TABLE_NAME + "." + AttackEntry.COLUMN_NAME_BSSID + " = " + "'" + BSSID + "'";
@@ -1306,14 +1306,38 @@ public class HostageDBOpenHelper extends SQLiteOpenHelper {
      * @param filter
      */
     public synchronized void deleteAttacksByFilter(LogFilter filter){
-        String selectQuery = this.selectionQueryFromFilter(filter, ""+ AttackEntry.TABLE_NAME + ", " +PacketEntry.TABLE_NAME);
-        String deleteQuery = selectQuery.replace("SELECT ","DELETE ");
+        String selectQuery = this.selectionQueryFromFilter(filter, "" + AttackEntry.COLUMN_NAME_ATTACK_ID);
+        String deletePacketQuery = "DELETE  FROM " + PacketEntry.TABLE_NAME + " WHERE "+ PacketEntry.TABLE_NAME + "."+ PacketEntry.COLUMN_NAME_ATTACK_ID+" in ( ";
+        deletePacketQuery = deletePacketQuery + selectQuery + " )";
+        String deleteAttacksQuery = "DELETE  FROM " + AttackEntry.TABLE_NAME + " WHERE "+ AttackEntry.TABLE_NAME + "."+ AttackEntry.COLUMN_NAME_ATTACK_ID+" in ( ";
+        deleteAttacksQuery =deleteAttacksQuery + selectQuery + " )";
 
         SQLiteDatabase db = this.getReadableDatabase();
-        db.execSQL(deleteQuery);
+        db.execSQL(deleteAttacksQuery);
+        db.execSQL(deletePacketQuery);
         db.close();
     }
 
+    public List<Long> getAllAttackIdsForFilter(LogFilter filter){
+        List<Long> results = new ArrayList<Long>();
+        SQLiteDatabase db = this.getReadableDatabase();
+        // Select All Query
+        String selectQuery = this.selectionQueryFromFilter(filter, "" + AttackEntry.COLUMN_NAME_ATTACK_ID);
+
+        Cursor cursor = db.rawQuery(selectQuery, null);
+
+        // looping through all rows and adding to list
+        if (cursor.moveToFirst()) {
+            do {
+                results.add(cursor.getLong(0));
+            } while (cursor.moveToNext());
+        }
+        cursor.close();
+        db.close();
+
+        return results;
+    }
+
     public ArrayList<MessageRecord> getMessageRecords(AttackRecord attackRecord , SQLiteDatabase db){
         ArrayList<MessageRecord> mr = new ArrayList<MessageRecord>();
 

+ 9 - 9
src/de/tudarmstadt/informatik/hostage/sync/android/SyncUtils.java

@@ -264,16 +264,16 @@ public class SyncUtils {
             JSONObject condition = new JSONObject();
 
             /**if(fromTime > 0){
-                Calendar calendar = GregorianCalendar.getInstance();
-                calendar.setTimeInMillis(fromTime);
+             Calendar calendar = GregorianCalendar.getInstance();
+             calendar.setTimeInMillis(fromTime);
 
-                condition.put("date", fromCalendar(calendar));
-            }**/
+             condition.put("date", fromCalendar(calendar));
+             }**/
 
             Location location = null;
             /**
              TODO(alex): UNCOMMENT THIS AGAIN, WHEN WE ARE SURE ABOUT USING LOCATIONS THIS WAY.
-            =======================================================================
+             =======================================================================
             location = MyLocationManager.getNewestLocation();
              */
             if(location != null){
@@ -409,8 +409,8 @@ public class SyncUtils {
             }
 
             sb.append(String.format("%s=%s",
-                urlEncodeUTF8(query[i]),
-                urlEncodeUTF8(query[i + 1])
+                    urlEncodeUTF8(query[i]),
+                    urlEncodeUTF8(query[i + 1])
             ));
         }
 
@@ -423,8 +423,8 @@ public class SyncUtils {
 
     public static String buildUrl(String protocol, String domain, int port, String path, String ... query){
         return buildUrlFromBase(
-            String.format("%s://%s:%d/%s", urlEncodeUTF8(protocol), urlEncodeUTF8(domain), port, path),
-            query
+                String.format("%s://%s:%d/%s", urlEncodeUTF8(protocol), urlEncodeUTF8(domain), port, path),
+                query
         );
     }
 

+ 6 - 6
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pBroadcastReceiver.java

@@ -91,7 +91,7 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
             // THE DEVICE LIST CHANGED
             // REQUEST THE LIST OF DEVICES
-            Log.d("DEBUG_WiFiP2pBroadcastReceiver", "P2P peers changed.");
+            Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - P2P peers changed.");
             if (manager != null) {
                 manager.requestPeers(channel, this);
             }
@@ -121,7 +121,7 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
                 }
             }
             if (this.networkState != networkInfo.getDetailedState()){
-                Log.d("DEBUG_WiFiP2pBroadcastReceiver", "P2P device network state changed to " + this.getDeviceNetworkStatus(networkInfo.getDetailedState()) + ".");
+                Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - P2P device network state changed to " + this.getDeviceNetworkStatus(networkInfo.getDetailedState()) + ".");
             }
             this.networkState = networkInfo.getDetailedState();
         } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
@@ -162,7 +162,7 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         peers.addAll(peerList.getDeviceList());
 
         if (peers.size() == 0) {
-            Log.d("DEBUG_WiFiP2pBroadcastReceiver", "No devices found");
+            Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - No devices found");
         }
 
         this.eventListener.discoveredDevices(peers);
@@ -205,7 +205,7 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
                 public void didSucceed() {
                     if (this.receiver.getOwnDevice().status != WifiP2pDevice.CONNECTED && isConnecting){
                         this.receiver.disconnect();
-                        Log.d("DEBUG_WiFiP2pBroadcastReceiver", "Cancel connection process.");
+                        Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - Cancel connection process.");
                         isConnecting = false;
                     }
                 }
@@ -282,11 +282,11 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
             @Override
             public void onSuccess() {
-                Log.d("DEBUG_WiFiP2pBroadcastReceiver", " Discovering Peers initiated.");
+                Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - Discovering Peers initiated.");
             }
             @Override
             public void onFailure(int reasonCode) {
-                Log.d("DEBUG_WiFiP2pBroadcastReceiver", " Discovering Peers failed. c="+reasonCode);
+                Log.d("DEBUG_WiFiP2p", "BroadcastReceiver - Discovering Peers failed. c="+reasonCode);
             }
         });
     }

+ 8 - 8
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pClientTask.java

@@ -66,7 +66,7 @@ public abstract class WiFiP2pClientTask extends BackgroundTask {
             try {
                 this.socket.close();
             } catch (IOException e) {
-                Log.e("DEBUG_WiFiP2pClientTask", e.getMessage());
+                Log.e("DEBUG_WiFiP2p", e.getMessage());
             }
         }
     }
@@ -82,22 +82,22 @@ public abstract class WiFiP2pClientTask extends BackgroundTask {
             this.socket = new Socket();
 
             try {
-                Log.d("DEBUG_WiFiP2pClientTask", "Opening client socket - ");
+                Log.d("DEBUG_WiFiP2p", "ClientTask - Opening client socket - ");
                 socket.bind(null);
                 socket.connect((new InetSocketAddress(hostIP, port())), time_out());
 
-                Log.d("DEBUG_WiFiP2pClientTask", "Client socket - " + socket.isConnected());
+                Log.d("DEBUG_WiFiP2p", "ClientTask socket - " + socket.isConnected());
                 this.handleConnection(socket);
 
-                Log.d("DEBUG_WiFiP2pClientTask", "Client: Data written");
+                Log.d("DEBUG_WiFiP2p", "ClientTask - Data written");
             } catch (ClassNotFoundException e){
-                Log.e("DEBUG_WiFiP2pClientTask", e.getMessage());
+                Log.e("DEBUG_WiFiP2p", e.getMessage());
                 e_message =  e.getLocalizedMessage();
                 if (e_message == null){
                     e_message = WiFiP2pServerTask.ERROR_COMMUNICATION_FAILED;// COMMUNICATION_ERROR
                 }
                 return e_message;            } catch (IOException e) {
-                Log.e("DEBUG_WiFiP2pClientTask", e.getMessage());
+                Log.e("DEBUG_WiFiP2p", e.getMessage());
 
                 if(this.isInterrupted()) {
                     this.interrupt(true);
@@ -106,7 +106,7 @@ public abstract class WiFiP2pClientTask extends BackgroundTask {
 
                 long seconds_to_wait = (long) Math.min(60, Math.pow(2, 1));
                 tryNum++;
-                Log.i("DEBUG_WiFiP2pClientTask", "could not connect to server. Will try again in " + 1 + "s");
+                Log.i("DEBUG_WiFiP2p", "ClientTaskError - could not connect to server. Will try again in " + 1 + "s");
                 try {
                     Thread.sleep(seconds_to_wait * time_out());
                 } catch (InterruptedException ie){
@@ -120,7 +120,7 @@ public abstract class WiFiP2pClientTask extends BackgroundTask {
                         } catch (IOException e) {
                             // Give up
                             e.printStackTrace();
-                            Log.d("DEBUG_WiFiP2p_Error"," Failed to close socket - "+ e.getLocalizedMessage());
+                            Log.d("DEBUG_WiFiP2p","ClientTaskError - Failed to close socket - "+ e.getLocalizedMessage());
                             e_message =  e.getLocalizedMessage();
                             if (e_message == null){
                                 e_message = WiFiP2pServerTask.ERROR_CONNECTION_FAILED;// FAILED TO CONNECT

+ 6 - 6
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pServerTask.java

@@ -75,7 +75,7 @@ public abstract class WiFiP2pServerTask extends BackgroundTask {
                 this.serverSocket.close();
             } catch (IOException e) {
                 String message = e.getLocalizedMessage() != null? e.getLocalizedMessage() : ERROR_MESSAGE_UNKNOWN;
-                Log.e("DEBUG_WiFiP2pServerTask", "" + message);
+                Log.e("DEBUG_WiFiP2p", "ServerTask - " + message);
             }
         }
     }
@@ -93,10 +93,10 @@ public abstract class WiFiP2pServerTask extends BackgroundTask {
                 this.serverSocket = new ServerSocket(WiFiP2pClientTask.port());
                 //serverSocket.setReuseAddress(true);
                 //serverSocket.bind(new InetSocketAddress(WiFiP2pClientTask.port()));
-                Log.d("DEBUG_WiFiP2pServerTask", "Server: Socket opened");
+                Log.d("DEBUG_WiFiP2p", "ServerTask - Socket opened");
                 this.serverSocket.setSoTimeout(this.getTimeoutSeconds() * 1000);
                 Socket client = this.serverSocket.accept();
-                Log.d("DEBUG_WiFiP2pServerTask", "Server: connection done");
+                Log.d("DEBUG_WiFiP2p", "ServerTask - connection done");
 
                 this.handleConnection(client, this.serverSocket);
 
@@ -106,7 +106,7 @@ public abstract class WiFiP2pServerTask extends BackgroundTask {
                 return BACKGROUND_TASK_MESSAGE_SUCCESS;
             } catch (ClassNotFoundException e){
                 e.printStackTrace();
-                Log.e("DEBUG_WiFiP2pServerTask", "" + e.getMessage());
+                Log.e("DEBUG_WiFiP2p", "ServerTask - " + e.getMessage());
                 String e_message =  null;
                 e_message = e.getLocalizedMessage();
                 if (e_message == null){
@@ -117,10 +117,10 @@ public abstract class WiFiP2pServerTask extends BackgroundTask {
                 try {
                     if (!this.serverSocket.isClosed()) this.serverSocket.close();
                 }catch (IOException ec){
-                    Log.e("DEBUG_WiFiP2pServerTask", "Could not close server socket.");
+                    Log.e("DEBUG_WiFiP2p", "ServerTask - Could not close server socket.");
                 }
                 e.printStackTrace();
-                Log.e("DEBUG_WiFiP2pServerTask", "" + e.getMessage());
+                Log.e("DEBUG_WiFiP2p", "ServerTask - " + e.getMessage());
                 String e_message = e.getLocalizedMessage();
                 if (e_message == null){
                     e_message = ERROR_MESSAGE_UNKNOWN;// UNKNOWN_ERROR

+ 13 - 13
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/ui/WiFiP2pSyncActivity.java

@@ -207,20 +207,20 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
                 @Override
                 public void discoveredDevices(List<WifiP2pDevice> peers) {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Actualise devices list");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Actualise devices list");
                     this.activity.updateDeviceListView(peers);
                 }
 
                 @Override
                 public void wifiP2pIsEnabled(boolean enabled) {
                     String tmp = enabled? "enabled" : "disabled";
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Peer to peer is " + tmp + ".");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Peer to peer is " + tmp + ".");
                     this.activity.setWifiDirectAvailable(enabled);
                 }
 
                 @Override
                 public void didConnect(boolean isHost, WifiP2pInfo connectionInfo) {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Did connect");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Did connect");
 
                     this.activity.progressDialog.setMessage(PROGRESS_MESSAGE_LOADING);
                     if (!this.activity.progressDialog.isShowing()){
@@ -229,17 +229,17 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
                     this.activity.setHost(isHost);
                     if (isHost){
-                        Log.d("DEBUG_WiFiP2pSyncActivity", "Connected as HOST");
+                        Log.d("DEBUG_WiFiP2p", "Activity - Connected as HOST");
                         this.activity.startHost();
                     } else {
-                        Log.d("DEBUG_WiFiP2pSyncActivity", "Connected as Client");
+                        Log.d("DEBUG_WiFiP2p", "Activity - Connected as Client");
                         this.activity.startClient(connectionInfo);
                     }
                 }
 
                 @Override
                 public void failedToConnect() {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Failed to connect");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Failed to connect");
                     Toast.makeText(this.activity, COULD_NOT_CONNECT_MESSAGE , Toast.LENGTH_LONG).show();
                     if (this.activity.progressDialog != null){
                         this.activity.progressDialog.dismiss();
@@ -248,7 +248,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
                 @Override
                 public void didDisconnect() {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Did disconnect");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Did disconnect");
                     if (this.activity.progressDialog != null){
                         this.activity.progressDialog.dismiss();
                     }
@@ -256,7 +256,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
                 @Override
                 public void failedToDisconnect() {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Failed to disconnect");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Failed to disconnect");
                     //Toast.makeText(this.activity, "Could not disconnect with device. Retry.", Toast.LENGTH_LONG).show();
                     // Other device did disconnect a while before.
                     if (this.activity.progressDialog != null &&
@@ -271,7 +271,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
                 @Override
                 public void ownDeviceInformationIsUpdated(WifiP2pDevice device) {
-                    Log.d("DEBUG_WiFiP2pSyncActivity", "Updated device " + device.deviceName + " " + device.deviceAddress + ".");
+                    Log.d("DEBUG_WiFiP2p", "Activity - Updated device " + device.deviceName + " " + device.deviceAddress + ".");
                     this.activity.updateOwnDeviceInformation(device);
                     this.activity.searchForDevices();
                 }
@@ -372,7 +372,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
                 return this;
             }
         }.init(this.mLstP2PDevices));
-        Log.d("DEBUG_WiFiP2pSyncActivity", " Discovered "+peers.size()+" devices.");
+        Log.d("DEBUG_WiFiP2p", "Activity - Discovered "+peers.size()+" devices.");
 
         if (peers.size() == 0){
             this.searchForDevices();
@@ -386,13 +386,13 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     {
 
         //if (this.hostTask == null || this.hostTask.isInterrupted()){
-            Log.d("DEBUG_WiFiP2pSyncActivity", "Starting HOST Task");
+            Log.d("DEBUG_WiFiP2p", "Activity - Starting HOST Task");
             //Toast.makeText(this, PERFORMING_TASK_AS_HOST , Toast.LENGTH_SHORT).show();
             this.hostTask = new SyncHostTask(this.ownDevice, this.syncCompletionListener(), getApplicationContext());
             this.executingTask = this.hostTask;
             this.hostTask.execute();
         //} else {
-        //    Log.d("DEBUG_WiFiP2pSyncActivity", "Preventing third device for any syncing.");
+        //    Log.d("DEBUG_WiFiP2p", "Activity - Preventing third device for any syncing.");
         //}
     }
 
@@ -402,7 +402,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
      */
     private void startClient(WifiP2pInfo info)
     {
-           Log.d("DEBUG_WiFiP2pSyncActivity", "Starting CLIENT Task");
+           Log.d("DEBUG_WiFiP2p", "Activity - Starting CLIENT Task");
            this.clientTask = new SyncClientTask( info.groupOwnerAddress.getHostAddress(),this.ownDevice, this.syncCompletionListener(), getApplicationContext() );
            this.executingTask = this.clientTask;
            this.clientTask.execute();

+ 39 - 37
src/de/tudarmstadt/informatik/hostage/ui/fragment/HomeFragment.java

@@ -17,8 +17,6 @@ import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.support.v4.content.LocalBroadcastManager;
-import android.text.Html;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -135,9 +133,6 @@ public class HomeFragment extends Fragment {
 	}
 
 	public void setStateActive(boolean initial) {
-		mHomeTextAttacks.setVisibility(View.VISIBLE);
-		mHomeTextSecurity.setVisibility(View.VISIBLE);
-
 		mHomeTextName.setTextColor(mDefaultTextColor);
 		mHomeTextProfile.setTextColor(mDefaultTextColor);
 		mHomeTextProfileHeader.setTextColor(mDefaultTextColor);
@@ -159,6 +154,8 @@ public class HomeFragment extends Fragment {
 	}
 
 	public void setStateConnected() {
+		mHomeTextAttacks.setVisibility(View.VISIBLE);
+		mHomeTextSecurity.setVisibility(View.VISIBLE);
 		mHomeTextProfile.setVisibility(View.VISIBLE);
 		mHomeTextProfileHeader.setVisibility(View.VISIBLE);
 		mHomeProfileImage.setVisibility(View.VISIBLE);
@@ -182,7 +179,8 @@ public class HomeFragment extends Fragment {
 		}
 
 		boolean hasActiveListeners = false;
-		int totalAttacks = mDbHelper.numBssidSeen(mConnectionInfo.getString(getString(R.string.connection_info_bssid), null));
+		int totalAttacks = mDbHelper.getNumAttacksSeenByBSSID(
+				mConnectionInfo.getString(getString(R.string.connection_info_bssid), null));
 
 		if (MainActivity.getInstance().getHostageService() != null) {
 			if (MainActivity.getInstance().getHostageService().hasRunningListeners()) {
@@ -198,41 +196,45 @@ public class HomeFragment extends Fragment {
 			}
 		}
 
+		if (isConnected) {
+			if (totalAttacks == 0) {
+				mHomeTextAttacks.setText(R.string.zero_attacks);
+				mHomeTextSecurity.setText(R.string.secure);
+			} else {
+				mHomeTextAttacks.setText(totalAttacks
+						+ (totalAttacks == 1 ? getResources().getString(R.string.attack) : getResources().getString(R.string.attacks))
+						+ getResources().getString(R.string.recorded));
+				mHomeTextSecurity.setText(R.string.insecure);
+			}
+		} else {
+			mHomeTextAttacks.setText("");
+			mHomeTextSecurity.setText("");
+		}
+
 		if (hasActiveListeners) {
 			setStateActive(true);
 
-			if(!isConnected){
-				ThreatIndicatorGLRenderer.setThreatLevel(ThreatIndicatorGLRenderer.ThreatLevel.NO_THREAT);
-				mHomeTextAttacks.setText("");
-				mHomeTextSecurity.setText("");
-			} else {
-				switch (mThreatLevel) {
-					case NO_THREAT:
-						mHomeTextAttacks.setText(R.string.zero_attacks);
-						mHomeTextSecurity.setText(R.string.secure);
-						mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_dark_green));
-						mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_dark_green));
-						break;
-					case PAST_THREAT:
-						mHomeTextAttacks.setText(totalAttacks
-								+ (totalAttacks == 1 ? getResources().getString(R.string.attack) : getResources().getString(R.string.attacks))
-								+ getResources().getString(R.string.recorded));
-						mHomeTextSecurity.setText(R.string.insecure);
-						mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_yellow));
-						mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_yellow));
-						break;
-					case LIVE_THREAT:
-						mHomeTextAttacks.setText(totalAttacks
-								+ (totalAttacks == 1 ? getResources().getString(R.string.attack) : getResources().getString(R.string.attacks))
-								+ getResources().getString(R.string.recorded));
-						mHomeTextSecurity.setText(R.string.insecure);
-						mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_red));
-						mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_red));
-						break;
-				}
-
-				ThreatIndicatorGLRenderer.setThreatLevel(mThreatLevel);
+			// color text according to threat level
+			switch (mThreatLevel) {
+				case NO_THREAT:
+					mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_dark_green));
+					mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_dark_green));
+					break;
+				case PAST_THREAT:
+					mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_yellow));
+					mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_yellow));
+					break;
+				case LIVE_THREAT:
+					mHomeTextAttacks.setText(totalAttacks
+							+ (totalAttacks == 1 ? getResources().getString(R.string.attack) : getResources().getString(R.string.attacks))
+							+ getResources().getString(R.string.recorded));
+					mHomeTextSecurity.setText(R.string.insecure);
+					mHomeTextAttacks.setTextColor(getResources().getColor(R.color.holo_red));
+					mHomeTextSecurity.setTextColor(getResources().getColor(R.color.holo_red));
+					break;
 			}
+
+			ThreatIndicatorGLRenderer.setThreatLevel(mThreatLevel);
 		} else {
 			setStateNotActive();
 		}

+ 10 - 17
src/de/tudarmstadt/informatik/hostage/ui/fragment/PreferenceHostageFragment.java

@@ -10,7 +10,9 @@ import android.preference.PreferenceFragment;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.sync.android.SyncUtils;
@@ -23,9 +25,9 @@ import de.tudarmstadt.informatik.hostage.sync.android.SyncUtils;
 */
 public class PreferenceHostageFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
 	/**
-	 * Maps an text preference to an suffix string
+	 * Contains preferences for which to display a preview of the value in the summary
 	 */
-	private HashMap<String, String> mSuffixMap;
+	private HashSet<String> mPrefValuePreviewSet;
 
 	/**
 	 * {@inheritDoc}
@@ -47,12 +49,9 @@ public class PreferenceHostageFragment extends PreferenceFragment implements Sha
 				"pref_portscan_timeout"
 		};
 
-		// map the text preferences to suffixes
-		this.mSuffixMap = new HashMap<String, String>();
-		this.mSuffixMap.put("pref_timeout", "s");
-		this.mSuffixMap.put("pref_sleeptime", "ms");
-		this.mSuffixMap.put("pref_location_time", "ms");
-		this.mSuffixMap.put("pref_portscan_timeout", "s");
+		mPrefValuePreviewSet = new HashSet<String>();
+		mPrefValuePreviewSet.add("pref_external_location");
+		mPrefValuePreviewSet.add("pref_upload_server");
 
 		addPreferencesFromResource(R.xml.settings_preferences);
 
@@ -69,15 +68,9 @@ public class PreferenceHostageFragment extends PreferenceFragment implements Sha
 		Preference p = findPreference(key);
 		SharedPreferences sharedPreferences = this.getPreferenceManager().getSharedPreferences();
 
-		if(p != null && p instanceof EditTextPreference){
-			String suffix = "";
-
-			if(this.mSuffixMap.containsKey(key)){
-				suffix = this.mSuffixMap.get(key);
-			}
-
-			if (p.getSummary() == null) {
-				p.setSummary(sharedPreferences.getString(key, "") + " " + suffix);
+		if(p != null && p instanceof EditTextPreference) {
+			if (mPrefValuePreviewSet.contains(key)) {
+				p.setSummary(sharedPreferences.getString(key, ""));
 			}
 		}
 	}

+ 10 - 7
src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordDetailFragment.java

@@ -15,6 +15,7 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;
@@ -59,7 +60,7 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 	private TextView mRecordDetailsTextBssid;
 	private TextView mRecordDetailsTextRemoteip;
 	private TextView mRecordDetailsTextProtocol;
-	private Button mRecordDeleteButton;
+	private ImageButton mRecordDeleteButton;
 
 	/**
 	 * Sets the record of which the details should be displayed
@@ -134,7 +135,7 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 		mRecordDetailsTextBssid = (TextView) view.findViewById(R.id.record_details_text_bssid);
 		mRecordDetailsTextRemoteip = (TextView) view.findViewById(R.id.record_details_text_remoteip);
 		mRecordDetailsTextProtocol = (TextView) view.findViewById(R.id.record_details_text_protocol);
-		mRecordDeleteButton = (Button) view.findViewById(R.id.record_delete_button);
+		mRecordDeleteButton = (ImageButton) view.findViewById(R.id.DeleteButton);
 	}
 
 
@@ -178,11 +179,13 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 				@Override
 				public boolean onTouch(final View v, final MotionEvent motionEvent) {
 					if (v.getId() == R.id.record_conversation_content) {
-						v.getParent().requestDisallowInterceptTouchEvent(true);
-						switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
-						case MotionEvent.ACTION_UP:
-							v.getParent().requestDisallowInterceptTouchEvent(false);
-							break;
+						if (v.canScrollVertically(1) || v.canScrollVertically(-1)) { // if the view is scrollable
+							v.getParent().requestDisallowInterceptTouchEvent(true);
+							switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
+								case MotionEvent.ACTION_UP:
+									v.getParent().requestDisallowInterceptTouchEvent(false);
+									break;
+							}
 						}
 					}
 					return false;

+ 74 - 9
src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordOverviewFragment.java

@@ -4,12 +4,15 @@ import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.FragmentManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -36,6 +39,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Random;
 
+import de.tudarmstadt.informatik.hostage.Handler;
 import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.logging.AttackRecord;
@@ -58,6 +62,7 @@ import de.tudarmstadt.informatik.hostage.ui.dialog.DateTimeDialogFragment;
 import de.tudarmstadt.informatik.hostage.ui.model.ExpandableListItem;
 import de.tudarmstadt.informatik.hostage.ui.model.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui.model.LogFilter.SortType;
+import de.tudarmstadt.informatik.hostage.ui.model.ServicesListItem;
 import de.tudarmstadt.informatik.hostage.ui.popup.AbstractPopup;
 import de.tudarmstadt.informatik.hostage.ui.popup.AbstractPopupItem;
 import de.tudarmstadt.informatik.hostage.ui.popup.SimplePopupItem;
@@ -109,6 +114,10 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 
     Thread loader;
 
+    private boolean mReceiverRegistered = false;
+    private BroadcastReceiver mReceiver;
+
+
 
     /* DATE CONVERSION STUFF*/
     static final DateFormat localisedDateFormatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
@@ -188,6 +197,14 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 
         this.initialiseListView();
 
+        ImageButton deleteButton = (ImageButton) rootView.findViewById(R.id.DeleteButton);
+        deleteButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                RecordOverviewFragment.this.openDeleteFilteredAttacksDialog();
+            }
+        });
+        deleteButton.setVisibility(this.showFilterButton? View.VISIBLE : View.INVISIBLE);
+
         ImageButton filterButton = (ImageButton) rootView.findViewById(R.id.FilterButton);
         filterButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
@@ -196,6 +213,7 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
         });
         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) {
@@ -212,6 +230,8 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
             }
         });
 
+        this.registerBroadcastReceiver();
+
 		return rootView;
 	 }
 
@@ -219,6 +239,7 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
     /**Initialises the expandable list view in a backgorund thread*/
     private void initialiseListView(){
         if (loader != null) loader.interrupt();
+        if (this.openSections == null) this.openSections = new ArrayList<Integer>();
 
         this.spinner.setVisibility(View.VISIBLE);
 
@@ -244,6 +265,9 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 
                                 if (adapter.getGroupCount() >= 1){
                                     RecordOverviewFragment.this.expListView.expandGroup(DEFAULT_GROUPING_KEY_INDEX);
+                                    if (!RecordOverviewFragment.this.openSections.contains(DEFAULT_GROUPING_KEY_INDEX)){
+                                        RecordOverviewFragment.this.openSections.add(DEFAULT_GROUPING_KEY_INDEX);
+                                    }
                                 } else {
                                     RecordOverviewFragment.this.setSectionToOpen(RecordOverviewFragment.this.sectionToOpen);
                                 }
@@ -346,7 +370,6 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 	}
 
 
-
     @Override
     public void onStart() {
         super.onStart();
@@ -360,7 +383,15 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
 
     }
 
-	@Override
+    @Override
+    public void onDestroy(){
+        if (mReceiver != null){
+        }
+        super.onDestroy();
+    }
+
+
+    @Override
 	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
 		// Inflate the menu items for use in the action bar
 		inflater.inflate(R.menu.records_overview_actions, menu);
@@ -431,11 +462,15 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
         // Use the Builder class for convenient dialog construction
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 
-        String deleteAttacksTitle = MainActivity.getInstance().getString(R.string.deleteAttacksTitle);
+        String deleteFILTEREDAttacksTitle = MainActivity.getInstance().getString(R.string.deleteFILTEREDAttacksTitle);
+        String deleteALLAttacksTitle = MainActivity.getInstance().getString(R.string.deleteALLAttacksTitle);
+
         String cancelTitle = MainActivity.getInstance().getString(R.string.cancel);
         String deleteTitle = MainActivity.getInstance().getString(R.string.delete);
 
-        builder.setMessage(deleteAttacksTitle)
+        String text = this.filter.isSet()? deleteFILTEREDAttacksTitle : deleteALLAttacksTitle;
+
+        builder.setMessage(text)
                 .setPositiveButton(deleteTitle, new DialogInterface.OnClickListener() {
                     private RecordOverviewFragment recordOverviewFragment = null;
                     public void onClick(DialogInterface dialog, int id) {
@@ -595,6 +630,24 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
         }
     }
 
+    /**
+     * register a broadcast receiver if not already registered
+     * and also update the number of attacks per protocol
+     */
+    private void registerBroadcastReceiver() {
+        if (!mReceiverRegistered) {
+            mReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    RecordOverviewFragment.this.actualiseListViewInBackground();
+                }
+            };
+
+            LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mReceiver, new IntentFilter(getString(R.string.broadcast)));
+            this.mReceiverRegistered = true;
+        }
+    }
+
     /**
      * Actualises the list in a background thread
      */
@@ -625,12 +678,19 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
                             this.actualiseUI();
                         }
                         private void actualiseUI(){
+                            RecordOverviewFragment self = RecordOverviewFragment.this;
                             if (adapter != null){
-                                RecordOverviewFragment.this.expListView.setAdapter(adapter);
+                                self.expListView.setAdapter(adapter);
                                 adapter.notifyDataSetChanged();
-                                RecordOverviewFragment.this.spinner.setVisibility(View.GONE);
+                                self.spinner.setVisibility(View.GONE);
+                            }
+                            self.showEmptyDataNotification();
+                            if (self.openSections != null && self.expListView != null){
+                                for (int i = 0; i < self.openSections.size(); i++){
+                                    int index = self.openSections.get(i);
+                                    self.expListView.expandGroup(index);
+                                }
                             }
-                            RecordOverviewFragment.this.showEmptyDataNotification();
                         }
                     });
                 }
@@ -670,6 +730,9 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
                 int section = this.getGroupTitles().indexOf(this.sectionToOpen);
                 this.expListView.expandGroup(section);
                 this.sectionToOpen = "";
+                if (!this.openSections.contains(section)){
+                    RecordOverviewFragment.this.openSections.add(section);
+                }
             }
         }
     }
@@ -712,13 +775,15 @@ public class RecordOverviewFragment extends UpNavigatibleFragment implements Che
         mylist.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
             @Override
             public void onGroupExpand(int i) {
-                RecordOverviewFragment.this.openSections.add(new Integer(i));
+                if (!RecordOverviewFragment.this.openSections.contains(i)){
+                    RecordOverviewFragment.this.openSections.add(i);
+                }
             }
         });
         mylist.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
             @Override
             public void onGroupCollapse(int i) {
-                RecordOverviewFragment.this.openSections.remove(new Integer(i));
+                RecordOverviewFragment.this.openSections.remove(i);
             }
         });
 	}

+ 5 - 3
src/de/tudarmstadt/informatik/hostage/ui/fragment/ServicesFragment.java

@@ -3,7 +3,6 @@ package de.tudarmstadt.informatik.hostage.ui.fragment;
 import java.util.ArrayList;
 
 import android.app.AlertDialog;
-import android.app.Fragment;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -126,7 +125,9 @@ public class ServicesFragment extends TrackerFragment {
                     if (sender.equals(Handler.class.getName()) && values[0].equals(getString(R.string.broadcast_started))) {
                         for (ServicesListItem item : protocolList) {
                             if (item.protocol.equals(values[1])) {
-                                item.attacks = dbh.numBssidSeen(item.protocol, mConnectionInfo.getString(getString(R.string.connection_info_bssid), null));
+                                item.attacks = dbh.getNumAttacksSeenByBSSID(item.protocol,
+                                        mConnectionInfo.getString(
+                                                getString(R.string.connection_info_bssid), null));
                             }
                         }
                     }
@@ -174,7 +175,8 @@ public class ServicesFragment extends TrackerFragment {
         int i = 0;
         for (String protocol : protocols) {
             protocolList.add(new ServicesListItem(protocol));
-            protocolList.get(i).attacks = dbh.numBssidSeen(protocolList.get(i).protocol, mConnectionInfo.getString(getString(R.string.connection_info_bssid), null));
+            protocolList.get(i).attacks = dbh.getNumAttacksSeenByBSSID(protocolList.get(i).protocol,
+                    mConnectionInfo.getString(getString(R.string.connection_info_bssid), null));
             i++;
         }
 

+ 41 - 2
src/de/tudarmstadt/informatik/hostage/ui/fragment/ThreatMapFragment.java

@@ -10,14 +10,18 @@ import java.util.Map;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.FragmentManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.graphics.Color;
 import android.location.Criteria;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
 import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
 import android.text.Html;
 import android.view.InflateException;
 import android.view.LayoutInflater;
@@ -66,6 +70,10 @@ public class ThreatMapFragment extends TrackerFragment implements GoogleMap.OnIn
 	//private LocationClient mLocationClient;
 	private String mLocationProvider;
 
+	// needed for LIVE threat map
+	private boolean mReceiverRegistered = false;
+	private BroadcastReceiver mReceiver;
+
 	/**
 	 * if google play services aren't available an error notification will be displayed
 	 *
@@ -80,6 +88,27 @@ public class ThreatMapFragment extends TrackerFragment implements GoogleMap.OnIn
 		return result;
 	}
 
+	/**
+	 * register a broadcast receiver if not already registered
+	 * and also update the number of attacks per protocol
+	 */
+	private void registerBroadcastReceiver() {
+		if (!mReceiverRegistered) {
+			mReceiver = new BroadcastReceiver() {
+				@Override
+				public void onReceive(Context context, Intent intent) {
+					if (sMap != null) {
+						populateMap();
+					}
+				}
+			};
+
+			LocalBroadcastManager
+					.getInstance(getActivity()).registerReceiver(mReceiver, new IntentFilter(getString(R.string.broadcast)));
+			this.mReceiverRegistered = true;
+		}
+	}
+
 	/**
 	 * callback for when the info window of a marker gets clicked
 	 * open the RecordOverviewFragment and display all records belonging to an SSID
@@ -411,6 +440,8 @@ public class ThreatMapFragment extends TrackerFragment implements GoogleMap.OnIn
 			sMap.moveCamera(CameraUpdateFactory.newLatLngZoom(tudarmstadt, 13));
 
 			populateMap();
+
+			registerBroadcastReceiver();
 		}
 
 		// tell the user to enable wifi so map data can be streamed
@@ -434,12 +465,20 @@ public class ThreatMapFragment extends TrackerFragment implements GoogleMap.OnIn
 	@Override
 	public void onResume() {
 		super.onResume();
-		mLocationManager.requestLocationUpdates(mLocationProvider, 0, 1000.0f, this);
+		if (sMap != null) {
+			// repopulate
+			populateMap();
+		}
+		if (mLocationManager != null) {
+			mLocationManager.requestLocationUpdates(mLocationProvider, 0, 1000.0f, this);
+		}
 	}
 
 	@Override
 	public void onPause() {
 		super.onPause();
-		mLocationManager.removeUpdates(this);
+		if (mLocationManager != null) {
+			mLocationManager.removeUpdates(this);
+		}
 	}
 }