Browse Source

Error handling and localisation for wifi direct

Julien Clauter 9 years ago
parent
commit
689b89bf37

+ 10 - 7
res/layout/activity_p2_psync.xml

@@ -8,11 +8,13 @@
     android:paddingBottom="@dimen/activity_vertical_margin"
     tools:context="de.tudarmstadt.informatik.hostage.sync.p2p.P2PSyncActivity">
 
+
+
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceMedium"
-        android:text="Your Device"
+        android:text="@string/Your_Device"
         android:id="@+id/textView4"
         android:layout_alignParentLeft="true"
         android:layout_alignParentStart="true"
@@ -24,7 +26,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceSmall"
-        android:text="Change device name"
+        android:text="@string/Change_Device_Name"
         android:id="@+id/txtP2PChangeDeviceName"
         android:layout_alignParentTop="true"
         android:layout_alignParentRight="true"
@@ -49,7 +51,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceSmall"
-            android:text="Device name"
+            android:text="@string/Device_Name"
             android:id="@+id/textView"
             android:textStyle="bold" />
 
@@ -69,7 +71,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceSmall"
-            android:text="Device status"
+            android:text="@string/Device_Status"
             android:id="@+id/textView2"
             android:layout_below="@+id/textView"
             android:layout_alignParentLeft="true"
@@ -104,10 +106,11 @@
             android:visibility="gone"
             android:id="@+id/welcomeContainer">
 
+            <!-- We are sorry, but WiFi Direct does not seem to be supported by this device. -->
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="We are sorry, but WiFi Direct does not seem to be supported by this device."
+                android:text="@string/Wifi_Direct_Not_suppported"
                 android:id="@+id/txtP2PNotAvailable"
                 android:textAlignment="center"
                 android:gravity="center_horizontal"
@@ -128,7 +131,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:textAppearance="?android:attr/textAppearanceMedium"
-                android:text="Available Devices"
+                android:text="@string/Available_Devices"
                 android:id="@+id/textView5"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentLeft="true"
@@ -147,7 +150,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:textAppearance="?android:attr/textAppearanceSmall"
-                android:text="Looking for devices..."
+                android:text="@string/Looking_For_Devices_Progress_Title"
                 android:id="@+id/txtP2PSearchProgress"
                 android:layout_centerVertical="true"
                 android:layout_centerHorizontal="true" />

+ 33 - 0
res/values-de/strings.xml

@@ -152,6 +152,39 @@
     <string name="stats_per_cent_all">% von allen</string>
     <string name="pie_all">Alle</string>
 
+
+    <string name="CONNECTION_LOST_MESSAGE">Verbindung verloren, Wifi Direct muss erneut aktiviert werden.</string>
+    <string name="COULD_NOT_CONNECT_MESSAGE">Could not connect to device. Retry.</string>
+
+    <string name="SYNCHRONIZATION_COMPLETE_MESSAGE">Synchronisierung abgeschlossen.</string>
+    <string name="SYNCHRONIZATION_FAILED_MESSAGE">Synchronisierung konnte nicht abgeschlossen werden. Versuche es erneut.</string>
+
+    <string name="PERFORMING_TASK_AS_HOST">Verbunden als Host.</string>
+    <string name="PERFORMING_TASK_AS_CLIENT">Verbunden als Client.</string>
+
+    <string name="ACTIONBAR_TITLE">P2P Synchronisierung</string>
+    <string name="PROGRESS_TITLE_LOADING">Empfangen...</string>
+    <string name="PROGRESS_TITLE_CONNECTING">Verbinden...</string>
+
+    <string name="DEVICE_STATUS_AVAILABLE">Bereit</string>
+    <string name="DEVICE_STATUS_INVITED">Eingeladen</string>
+    <string name="DEVICE_STATUS_CONNECTED">Verbunden</string>
+    <string name="DEVICE_STATUS_FAILED">Fehlgeschlagen</string>
+    <string name="DEVICE_STATUS_UNAVAILABLE">Unerreichbar</string>
+    <string name="DEVICE_STATUS_UNKNOWN">Status ist unbekannt</string>
+
+    <string name="WIFI_STATUS_DISABLED_MESSAGE">WiFi Direct ist nicht vorhanden, bitte aktiviere WiFi Direct.</string>
+    <string name="WIFI_STATUS_ENABLE_BUTTON">Aktivieren</string>
+    <string name="CANCEL_BUTTON_TITLE">Abbrechen</string>
+
+    <string name="Your_Device">Eigene Ger&#228;te Informationen</string>
+    <string name="Change_Device_Name">Ger&#228;tename &#228;ndern</string>
+    <string name="Device_Name">Ger&#228;tename</string>
+    <string name="Device_Status">Ger&#228;testatus</string>
+    <string name="Wifi_Direct_Not_suppported">Das Ger&#228;t unterst&#252;tzt kein Wifi Direct.</string>
+    <string name="Available_Devices">Vorhandene Ger&#228;te</string>
+    <string name="Looking_For_Devices_Progress_Title">Suche andere Ger&#228;te.</string>
+
 	<string name="record_details_received">EMPFANGEN</string>
 	<string name="record_details_sent">GESENDET</string>
 	<string name="record_details_info" formatted="false">von %s an %s\n%s um %s Uhr</string>

+ 33 - 0
res/values/strings.xml

@@ -166,6 +166,39 @@
     <string name="stats_per_cent_all">% of all</string>
     <string name="pie_all">All</string>
 
+
+    <string name="CONNECTION_LOST_MESSAGE">Connection lost permanently, please enable wifi direct.</string>
+    <string name="COULD_NOT_CONNECT_MESSAGE">Could not connect to device. Retry.</string>
+
+    <string name="SYNCHRONIZATION_COMPLETE_MESSAGE">Synchronization complete.</string>
+    <string name="SYNCHRONIZATION_FAILED_MESSAGE">Could not synchronize devices. Retry</string>
+
+    <string name="PERFORMING_TASK_AS_HOST">Acting as Host.</string>
+    <string name="PERFORMING_TASK_AS_CLIENT">Acting as Client.</string>
+
+    <string name="ACTIONBAR_TITLE">WifiDirect Synchronization</string>
+    <string name="PROGRESS_TITLE_LOADING">Loading...</string>
+    <string name="PROGRESS_TITLE_CONNECTING">Connecting...</string>
+
+    <string name="DEVICE_STATUS_AVAILABLE">Available</string>
+    <string name="DEVICE_STATUS_INVITED">Invited</string>
+    <string name="DEVICE_STATUS_CONNECTED">Connected</string>
+    <string name="DEVICE_STATUS_FAILED">Failed</string>
+    <string name="DEVICE_STATUS_UNAVAILABLE">Unavailable</string>
+    <string name="DEVICE_STATUS_UNKNOWN">Unknown</string>
+
+    <string name="WIFI_STATUS_DISABLED_MESSAGE">WiFi Direct down, please enable WiFi Direct</string>
+    <string name="WIFI_STATUS_ENABLE_BUTTON">Enable WiFi Direct</string>
+    <string name="CANCEL_BUTTON_TITLE">Cancel</string>
+
+    <string name="Your_Device">Own Device Information</string>
+    <string name="Change_Device_Name">Change your device name</string>
+    <string name="Device_Name">Device Name</string>
+    <string name="Device_Status">Device Status</string>
+    <string name="Wifi_Direct_Not_suppported">Your device does not support Wifi Direct.</string>
+    <string name="Available_Devices">Available Devices</string>
+    <string name="Looking_For_Devices_Progress_Title">Scanning for other devices.</string>
+
 	<string name="record_details_received">RECEIVED</string>
 	<string name="record_details_sent">SENT</string>
 	<string name="record_details_info" formatted="false">from %s to %s\n%s at %s</string>

+ 21 - 12
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/BackgroundTask.java

@@ -8,6 +8,9 @@ import android.os.AsyncTask;
  */
 public class BackgroundTask extends AsyncTask<Void, Void, String> {
 
+    /**
+     * This listener calls didSucceed if the method performInBackground will return true, otherwise it calls didFail.
+     */
     public interface BackgroundTaskCompletionListener {
         public void didSucceed();
         public void didFail();
@@ -15,6 +18,8 @@ public class BackgroundTask extends AsyncTask<Void, Void, String> {
 
     private boolean isInterrupted;
 
+    private boolean wasSuccessfully;
+
     public void interrupt(boolean b){
         this.isInterrupted = b;
     }
@@ -30,28 +35,26 @@ public class BackgroundTask extends AsyncTask<Void, Void, String> {
         this.completion_listener = l;
     }
 
+    /**
+     * Interrupts the background process.
+     * @param isInterrupted
+     */
     public void setInterrupted(boolean isInterrupted) {
         this.isInterrupted = isInterrupted;
     }
 
 
-
+    /**
+     * Do any stuff here if it should run in the background. It should return true or false if the process was successfully.
+     * @return boolean
+     */
     public boolean performInBackground(){
         return true;
     }
 
     @Override
     protected String doInBackground(Void... params) {
-        boolean success = this.performInBackground();
-
-        if (this.completion_listener != null) {
-            if (success){
-                this.completion_listener.didSucceed();
-            }else {
-                this.completion_listener.didFail();
-            }
-        }
-
+        this.wasSuccessfully = this.performInBackground();
         return null;
     }
 
@@ -61,7 +64,13 @@ public class BackgroundTask extends AsyncTask<Void, Void, String> {
      */
     @Override
     protected void onPostExecute(String result) {
-
+        if (this.completion_listener != null) {
+            if (this.wasSuccessfully) {
+                this.completion_listener.didSucceed();
+            }else {
+                this.completion_listener.didFail();
+            }
+        }
     }
 
     /*

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

@@ -21,6 +21,10 @@ import java.util.List;
  */
 public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
 
+
+    /**
+     * This listener will inform about any wifi direct change.
+     */
     public interface WiFiP2pBroadcastListener {
         public void discoveredDevices(List<WifiP2pDevice> peers);
         public void wifiP2pIsEnabled(boolean enabled);
@@ -28,15 +32,15 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         public void failedToConnect();
         public void didDisconnect();
         public void failedToDisconnect();
-        public void deviceIsUpdated(WifiP2pDevice device);
+        public void ownDeviceInformationIsUpdated(WifiP2pDevice device);
     }
 
     private WifiP2pManager manager;
     private WifiP2pManager.Channel channel;
 
+    private WifiP2pDevice ownDevice;
+
     private android.net.NetworkInfo.DetailedState networkState = null;
-    //private WifiP2pManager.PeerListListener peerListListener;
-    //private WifiP2pManager.ConnectionInfoListener connectionInfoListener;
 
     static boolean setIsWifiP2pEnabled;
 
@@ -98,6 +102,9 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
                 // we are connected with the other device, request connection
                 // info to find group owner IP
                 manager.requestConnectionInfo(channel, this);
+                if (this.ownDevice == null){
+                    this.disconnect();
+                }
             } else {
                 if (networkInfo.getDetailedState() == android.net.NetworkInfo.DetailedState.DISCONNECTED){
                     isConnected = false;
@@ -113,7 +120,8 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
             this.networkState = networkInfo.getDetailedState();
         } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
             WifiP2pDevice device = intent.getParcelableExtra( WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
-            this.eventListener.deviceIsUpdated(device);
+            this.ownDevice = device;
+            this.eventListener.ownDeviceInformationIsUpdated(device);
         }
     }
 
@@ -134,12 +142,6 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         // socket.
 
         if (info.groupFormed){
-            if (info.isGroupOwner) {
-                //new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text)).execute();
-            } else  {
-                // The other device acts as the client. In this case, we enable the
-                // get file button.
-            }
             this.eventListener.didConnect(info.isGroupOwner, info);
         }
     }
@@ -160,31 +162,39 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         // DISMISS PROGRESS IF NEEDED
     }
 
-
+    /**
+     * Connects to the given device.
+     * @param device
+     */
     public void connect(WifiP2pDevice device){
-        WifiP2pConfig config = new WifiP2pConfig();
-        config.deviceAddress = device.deviceAddress;
-        config.wps.setup = WpsInfo.PBC;
-        manager.connect(channel, config, new WifiP2pManager.ActionListener() {
-            private WiFiP2pBroadcastListener eventListener;
-            @Override
-            public void onSuccess() {
-                isConnected = true;
-                // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
-            }
+        if (device != null) {
+            WifiP2pConfig config = new WifiP2pConfig();
+            config.deviceAddress = device.deviceAddress;
+            config.wps.setup = WpsInfo.PBC;
+            manager.connect(channel, config, new WifiP2pManager.ActionListener() {
+                private WiFiP2pBroadcastListener eventListener;
+                @Override
+                public void onSuccess() {
+                    isConnected = true;
+                    // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
+                }
 
-            @Override
-            public void onFailure(int reason) {
-                this.eventListener.failedToConnect();
-            }
+                @Override
+                public void onFailure(int reason) {
+                    this.eventListener.failedToConnect();
+                }
 
-            public WifiP2pManager.ActionListener init(WiFiP2pBroadcastListener eventListener){
-                this.eventListener = eventListener;
-                return this;
-            }
-        }.init(this.eventListener));
+                public WifiP2pManager.ActionListener init(WiFiP2pBroadcastListener eventListener){
+                    this.eventListener = eventListener;
+                    return this;
+                }
+            }.init(this.eventListener));
+        }
     }
 
+    /**
+     * Disconnects from the connected wifi direct group if the own device is still connected.
+     */
     public void disconnect() {
         if (isConnected){
             manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
@@ -209,6 +219,10 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         }
     }
 
+    /**
+     * Discover other devices.
+     * The WiFiP2pBroadcastListener will inform about any change.
+     */
     public void discoverDevices(){
         manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
             @Override
@@ -222,9 +236,13 @@ public class WiFiP2pBroadcastReceiver extends BroadcastReceiver implements WifiP
         });
     }
 
-
-    private String getDeviceNetworkStatus(android.net.NetworkInfo.DetailedState deviceStatus) {
-        switch (deviceStatus) {
+    /**
+     * Returns a string representation of the given network status.
+     * @param networkStatus network status
+     * @return localised network status string
+     */
+    private String getDeviceNetworkStatus(android.net.NetworkInfo.DetailedState networkStatus) {
+        switch (networkStatus) {
             case DISCONNECTED: {
                 return "Disconnected";
             }

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

@@ -1,5 +1,7 @@
 package de.tudarmstadt.informatik.hostage.sync.wifi_direct;
 
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -12,14 +14,23 @@ import java.net.Socket;
 
 /**
  * Created by Julien on 07.01.2015.
+ *
+ * The client task.
+ *
+ * The client is the initial actor and will try to connect to the host as long as the task is not interrupted or successfully connected to the host.
+ *
+ *
  */
-public class WiFiP2pClientTask extends BackgroundTask {
-
+public abstract class WiFiP2pClientTask extends BackgroundTask {
 
+    // Set the port here for the client and host task.
+    public static int DEFAULT_WIFI_PORT = 1029;
 
     private String hostIP;
     private Socket socket;
 
+    private WifiP2pDevice ownDevice;
+
     public String getHostIP() {
         return hostIP;
     }
@@ -29,16 +40,17 @@ public class WiFiP2pClientTask extends BackgroundTask {
     }
 
 
-    public int port(){
-        return 8988;
+    public static int port(){
+        return DEFAULT_WIFI_PORT;
     }
-    public int time_out(){
+    public static int time_out(){
         return 1000;
     }
 
 
-    public WiFiP2pClientTask(String hostIP, BackgroundTaskCompletionListener l){
+    public WiFiP2pClientTask(String hostIP, WifiP2pDevice ownDevice, BackgroundTaskCompletionListener l){
         super(l);
+        this.ownDevice = ownDevice;
         this.hostIP = hostIP;
     }
 
@@ -58,13 +70,14 @@ public class WiFiP2pClientTask extends BackgroundTask {
     @Override
     public boolean performInBackground(){
         int tryNum = 1;
-        while (!this.isInterrupted()){
+        int max_tries = 10;
+        while (!this.isInterrupted() && tryNum <= max_tries){
             this.socket = new Socket();
 
             try {
                 Log.d("WiFiP2pClientTask", "Opening client socket - ");
                 socket.bind(null);
-                socket.connect((new InetSocketAddress(hostIP, this.port())), this.time_out());
+                socket.connect((new InetSocketAddress(hostIP, port())), time_out());
 
                 Log.d("WiFiP2pClientTask", "Client socket - " + socket.isConnected());
                 this.handleConnection(socket);
@@ -81,10 +94,11 @@ public class WiFiP2pClientTask extends BackgroundTask {
                     break;
                 }
 
-                long seconds_to_wait = (long) Math.min(60, Math.pow(2, tryNum));
+                long seconds_to_wait = (long) Math.min(60, Math.pow(2, 1));
+                tryNum++;
                 Log.i("WiFiP2pClientTask", "could not connect to server. Will try again in " + seconds_to_wait + "s");
                 try {
-                    Thread.sleep(seconds_to_wait * 1000);
+                    Thread.sleep(seconds_to_wait * time_out());
                 } catch (InterruptedException ie){
                     ie.printStackTrace();
                 }
@@ -103,11 +117,16 @@ public class WiFiP2pClientTask extends BackgroundTask {
                 }
             }
         }
-        return true;
+        return tryNum <= max_tries;
     }
 
 
-
+    /**
+     * Initiates the client task and sends the first response to the host.
+     * @param client the client socket
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
     private void handleConnection(Socket client) throws IOException, ClassNotFoundException {
 
         InputStream is = client.getInputStream();
@@ -122,6 +141,7 @@ public class WiFiP2pClientTask extends BackgroundTask {
             obj = null;
             WiFiP2pSerializableObject toSend = this.handleReceivedObject(receivedObj);
             if (toSend != null) {
+                toSend.setActingDevice_IP_address(this.ownDevice.deviceAddress);
                 oos.writeObject(toSend);
                 oos.flush();
                 oos.reset();
@@ -137,9 +157,11 @@ public class WiFiP2pClientTask extends BackgroundTask {
         this.interrupt(true);
     }
 
-    public WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj){
-
-        return null;
-    }
-
+    /**
+     * This method is initially called with a null parameter to inform about a initial state.
+     * Return null to disable the client task.
+     * @param receivedObj the response for the last request, null if it is the first call on the host.
+     * @return WiFiP2pSerializableObject request object
+     */
+    public abstract WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj);
 }

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

@@ -3,6 +3,7 @@ package de.tudarmstadt.informatik.hostage.sync.wifi_direct;
 import android.app.Activity;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pManager;
 
@@ -11,8 +12,11 @@ import android.net.wifi.p2p.WifiP2pManager;
  */
 public class WiFiP2pEventHandler implements WifiP2pManager.ChannelListener {
 
+    /**
+     * The WiFiP2pEventListener informs about all wifi direct changes.
+     */
     public interface WiFiP2pEventListener extends WiFiP2pBroadcastReceiver.WiFiP2pBroadcastListener{
-
+         public void onConnectionLost();
     }
 
     private WifiP2pManager manager;
@@ -38,24 +42,33 @@ public class WiFiP2pEventHandler implements WifiP2pManager.ChannelListener {
 
         manager = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE);
         channel = manager.initialize(activity, activity.getMainLooper(), this);
+    }
 
-        //receiver = new WiFiP2pBroadcastReceiver(manager, channel, this.eventListener);
-        //activity.registerReceiver(receiver, intentFilter);
+    public void setOnRetryIfTheChannelIsLost(boolean shouldRetry){
+        this.retryChannel = shouldRetry;
+    }
+    public boolean isRetryingIfTheChannelIsLost(){
+        return this.retryChannel;
     }
 
-    public void onResume() {
+    /**
+     * Call this method if the app comes back to foreground. E.g. in the onResume from the activity.
+     */
+    public void startService() {
         if (receiver == null){
             receiver = new WiFiP2pBroadcastReceiver(manager, channel, this.eventListener);
             activity.registerReceiver(receiver, intentFilter);
         }
     }
 
-    public void onPause() {
+    /**
+     * Call this method to disabled wifi direct while the app is in the background.  E.g. in the onPause from the activity.
+     */
+    public void stopService() {
         if (receiver != null) {
             activity.unregisterReceiver(receiver);
             receiver = null;
         }
-
     }
 
     @Override
@@ -64,21 +77,33 @@ public class WiFiP2pEventHandler implements WifiP2pManager.ChannelListener {
         if (manager != null && !retryChannel) {
             retryChannel = true;
             manager.initialize(this.activity, this.activity.getMainLooper(), this);
+            receiver = new WiFiP2pBroadcastReceiver(manager, channel, this.eventListener);
+            activity.registerReceiver(receiver, intentFilter);
         } else {
-
+            this.eventListener.onConnectionLost();
         }
     }
 
+    /**
+     * Connect your device to the given device.
+     * @param device
+     */
     public void connect(WifiP2pDevice device){
-        if (this.receiver != null)
+        if (this.receiver != null && device != null)
             this.receiver.connect(device);
     }
 
+    /**
+     * Disconnect from the connected wifi group.
+     */
     public void disconnect() {
         if (this.receiver != null)
             this.receiver.disconnect();
     }
 
+    /**
+     * Discover all available wifi direct device in the current environment.
+     */
     public void discoverDevices(){
         if (this.receiver != null)
             this.receiver.discoverDevices();

+ 18 - 5
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/WiFiP2pSerializableObject.java

@@ -4,10 +4,16 @@ import java.io.Serializable;
 
 /**
  * Created by Julien on 07.01.2015.
+ *
+ * An instance of this class is send from client to host and another one will be send back as response.
+ * You can create subclass for any variation. Any information will be transferred.
+ *
  */
 public class WiFiP2pSerializableObject implements Serializable {
 
-    private String methodName;
+    private String requestIdentifier;
+    private String actingDevice_IP_address;
+
 
     public Serializable getObjectToSend() {
         return objectToSend;
@@ -19,11 +25,18 @@ public class WiFiP2pSerializableObject implements Serializable {
 
     private Serializable objectToSend;
 
-    public void setMethodName(String m){
-        this.methodName = m;
+    public void setRequestIdentifier(String m){
+        this.requestIdentifier = m;
+    }
+    public String getRequestIdentifier(){
+        return this.requestIdentifier;
     }
-    public String getMethodName(){
-        return this.methodName;
+
+    public String getActingDevice_IP_address() {
+        return actingDevice_IP_address;
     }
 
+    public void setActingDevice_IP_address(String actingDevice_IP_address) {
+        this.actingDevice_IP_address = actingDevice_IP_address;
+    }
 }

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

@@ -1,5 +1,7 @@
 package de.tudarmstadt.informatik.hostage.sync.wifi_direct;
 
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -12,11 +14,25 @@ import java.net.Socket;
 
 /**
  * Created by Julien on 07.01.2015.
+ *
+ * The Server Task.
+ *
+ * The Server task is waiting as long as a client is connecting to it.
+ * As a result of this the main part and process will start after the client had send the first data.
+ *
+ * You never know how will become the host / server.
+ * So you need to implement a strategy if you want do send just from one specific device to the other.
+ *
+ *  * The server creates the object stream before the client can do it - to avoid a chicken and egg problem.
  */
-public class WiFiP2pServerTask extends BackgroundTask {
+public abstract class WiFiP2pServerTask extends BackgroundTask {
+
 
     private ServerSocket serverSocket;
 
+    private WifiP2pDevice ownDevice;
+
+
     @Override
     public void interrupt(boolean b){
         super.interrupt(b);
@@ -29,15 +45,16 @@ public class WiFiP2pServerTask extends BackgroundTask {
         }
     }
 
-    public WiFiP2pServerTask(BackgroundTaskCompletionListener l){
+    public WiFiP2pServerTask( WifiP2pDevice ownDevice, BackgroundTaskCompletionListener l){
         super(l);
+        this.ownDevice = ownDevice;
     }
 
     @Override
     public boolean performInBackground(){
         while (!this.isInterrupted()){
             try {
-                this.serverSocket = new ServerSocket(8988);
+                this.serverSocket = new ServerSocket(WiFiP2pClientTask.port());
                 Log.d("WiFiP2pServerTask", "Server: Socket opened");
                 Socket client = this.serverSocket.accept();
                 Log.d("WiFiP2pServerTask", "Server: connection done");
@@ -62,7 +79,13 @@ public class WiFiP2pServerTask extends BackgroundTask {
     }
 
 
-
+    /**
+     * The server creates the object stream before the client can do it to avoid a chicken and egg problem.
+     * @param client the client socket.
+     * @param server the server socket.
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
     private void handleConnection(Socket client, ServerSocket server) throws IOException, ClassNotFoundException {
         OutputStream os = client.getOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(os);
@@ -79,6 +102,7 @@ public class WiFiP2pServerTask extends BackgroundTask {
             obj = null;
             WiFiP2pSerializableObject toSend = this.handleReceivedObject(receivedObj);
             if (toSend != null) {
+                toSend.setActingDevice_IP_address(this.ownDevice.deviceAddress);
                 oos.writeObject(toSend);
                 oos.flush();
                 oos.reset();
@@ -97,8 +121,11 @@ public class WiFiP2pServerTask extends BackgroundTask {
         is.close();
     }
 
-    public WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj){
-
-        return null;
-    }
+    /**
+     * This method will be called if the server receives data from the client.
+     * Always return a WiFiP2pSerializableObject instance to give a simple response, otherwise the connection will be disconnected.
+     * @param receivedObj WiFiP2pSerializableObject the clients request
+     * @return WiFiP2pSerializableObject the response
+     */
+    abstract public WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj);
 }

+ 9 - 8
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/sync_tasks/SyncClientTask.java

@@ -1,6 +1,8 @@
 package de.tudarmstadt.informatik.hostage.sync.wifi_direct.sync_tasks;
 
 import android.content.Context;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
 import android.util.Log;
 
 import de.tudarmstadt.informatik.hostage.logging.SyncData;
@@ -20,9 +22,8 @@ public class SyncClientTask extends WiFiP2pClientTask {
     private HostageDBOpenHelper mdbh;
     private Synchronizer synchronizer;
 
-    public SyncClientTask(String hostIP, BackgroundTaskCompletionListener l, Context context) {
-        super(hostIP, l);
-
+    public SyncClientTask(String hostIP,  WifiP2pDevice ownDevice,BackgroundTaskCompletionListener l, Context context) {
+        super(hostIP, ownDevice, l);
         mdbh = new HostageDBOpenHelper(context);
         synchronizer = new Synchronizer(mdbh);
     }
@@ -36,13 +37,13 @@ public class SyncClientTask extends WiFiP2pClientTask {
             WiFiP2pSerializableObject syncObj = new WiFiP2pSerializableObject();
 
             syncObj.setObjectToSend(thisSyncInfo);
-            syncObj.setMethodName(SyncHostTask.SYNC_INFO_REQUEST);
+            syncObj.setRequestIdentifier(SyncHostTask.SYNC_INFO_REQUEST);
 
             return syncObj;
 
         } else {
-            Log.i("WiFiP2p_Client", "Received: " + receivedObj.getMethodName());
-            if (receivedObj.getMethodName().equals(SyncHostTask.SYNC_INFO_RESPONSE)) {
+            Log.i("WiFiP2p_Client", "Received: " + receivedObj.getRequestIdentifier());
+            if (receivedObj.getRequestIdentifier().equals(SyncHostTask.SYNC_INFO_RESPONSE)) {
                 SyncInfo sinfo = (SyncInfo) receivedObj.getObjectToSend();
 
                 if (sinfo != null && (sinfo instanceof SyncInfo)) {
@@ -51,12 +52,12 @@ public class SyncClientTask extends WiFiP2pClientTask {
                     WiFiP2pSerializableObject syncObj = new WiFiP2pSerializableObject();
 
                     syncObj.setObjectToSend(syncData);
-                    syncObj.setMethodName(SyncHostTask.SYNC_DATA_REQUEST);
+                    syncObj.setRequestIdentifier(SyncHostTask.SYNC_DATA_REQUEST);
 
                     return syncObj;
                 }
 
-            } else if (receivedObj.getMethodName().equals(SyncHostTask.SYNC_DATA_RESPONSE)) {
+            } else if (receivedObj.getRequestIdentifier().equals(SyncHostTask.SYNC_DATA_RESPONSE)) {
                 Log.i("WiFiP2p_Client", "Received Sync Data - ending sync process successfully." );
                 SyncData sdata = (SyncData) receivedObj.getObjectToSend();
 

+ 22 - 11
src/de/tudarmstadt/informatik/hostage/sync/wifi_direct/sync_tasks/SyncHostTask.java

@@ -1,8 +1,15 @@
 package de.tudarmstadt.informatik.hostage.sync.wifi_direct.sync_tasks;
 
 import android.content.Context;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
 import android.util.Log;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
 import de.tudarmstadt.informatik.hostage.logging.SyncData;
 import de.tudarmstadt.informatik.hostage.logging.SyncInfo;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
@@ -25,34 +32,37 @@ public class SyncHostTask extends WiFiP2pServerTask {
     private HostageDBOpenHelper mdbh;
     private Synchronizer synchronizer;
 
-    private SyncInfo receivedInfo;
+    private Map<String, SyncInfo> receivedInfoPerDevice;
 
-    public SyncHostTask(BackgroundTaskCompletionListener l , Context context) {
-        super(l);
+    public SyncHostTask(  WifiP2pDevice ownDevice, BackgroundTaskCompletionListener l , Context context) {
+        super(ownDevice , l);
         mdbh = new HostageDBOpenHelper(context);
         synchronizer = new Synchronizer(mdbh);
+
+        this.receivedInfoPerDevice = new HashMap<String, SyncInfo>();
     }
 
     @Override
     public WiFiP2pSerializableObject handleReceivedObject(WiFiP2pSerializableObject receivedObj){
         if (receivedObj != null) {
-            Log.i("WiFiP2p_Host", "Received: " + receivedObj.getMethodName());
+            Log.i("WiFiP2p_Host", "Received: " + receivedObj.getRequestIdentifier());
 
-            if (receivedObj.getMethodName().equals(SYNC_INFO_REQUEST)){
+            if (receivedObj.getRequestIdentifier().equals(SYNC_INFO_REQUEST)){
                 Log.i("WiFiP2p_Host", "Sending Sync Info: " + SYNC_INFO_RESPONSE);
 
-                this.receivedInfo = (SyncInfo) receivedObj.getObjectToSend();
+                SyncInfo syncInfo = (SyncInfo) receivedObj.getObjectToSend();
+                this.receivedInfoPerDevice.put(receivedObj.getActingDevice_IP_address(), syncInfo);
 
                 SyncInfo response = synchronizer.getSyncInfo();
                 WiFiP2pSerializableObject syncObj = new WiFiP2pSerializableObject();
 
                 syncObj.setObjectToSend(response);
-                syncObj.setMethodName(SYNC_INFO_RESPONSE);
+                syncObj.setRequestIdentifier(SYNC_INFO_RESPONSE);
 
                 return syncObj;
             }
 
-            if (receivedObj.getMethodName().equals(SYNC_DATA_REQUEST)){
+            if (receivedObj.getRequestIdentifier().equals(SYNC_DATA_REQUEST)){
                 Log.i("WiFiP2p_Host", "Sending Sync Data: " + SYNC_DATA_RESPONSE);
 
                 SyncData sdata = (SyncData) receivedObj.getObjectToSend();
@@ -61,12 +71,13 @@ public class SyncHostTask extends WiFiP2pServerTask {
                     synchronizer.updateFromSyncData(sdata);
                 }
 
-                if (this.receivedInfo != null){
-                    SyncData response = synchronizer.getSyncData(this.receivedInfo);
+                SyncInfo syncInfo = this.receivedInfoPerDevice.get(receivedObj.getActingDevice_IP_address());
+                if (syncInfo != null){
+                    SyncData response = synchronizer.getSyncData(syncInfo);
 
                     WiFiP2pSerializableObject syncObj = new WiFiP2pSerializableObject();
                     syncObj.setObjectToSend(response);
-                    syncObj.setMethodName(SYNC_DATA_RESPONSE);
+                    syncObj.setRequestIdentifier(SYNC_DATA_RESPONSE);
 
                     return syncObj;
                 }

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

@@ -1,11 +1,15 @@
 package de.tudarmstadt.informatik.hostage.sync.wifi_direct.ui;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pInfo;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -26,12 +30,39 @@ import de.tudarmstadt.informatik.hostage.sync.wifi_direct.BackgroundTask;
 import de.tudarmstadt.informatik.hostage.sync.wifi_direct.WiFiP2pEventHandler;
 import de.tudarmstadt.informatik.hostage.sync.wifi_direct.sync_tasks.SyncClientTask;
 import de.tudarmstadt.informatik.hostage.sync.wifi_direct.sync_tasks.SyncHostTask;
+import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
 
 /**
  * Created by Julien on 14.01.2015.
  */
 public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemClickListener {
 
+    public static String CONNECTION_LOST_MESSAGE = MainActivity.getContext().getString(R.string.CONNECTION_LOST_MESSAGE);// "Connection lost permanently, please enable wifi direct.";
+    public static String COULD_NOT_CONNECT_MESSAGE =MainActivity.getContext().getString(R.string.COULD_NOT_CONNECT_MESSAGE);// "Could not connect to device. Retry.";
+
+    public static String SYNCHRONIZATION_COMPLETE_MESSAGE =MainActivity.getContext().getString(R.string.SYNCHRONIZATION_COMPLETE_MESSAGE);// "Synchronization complete.";
+    public static String SYNCHRONIZATION_FAILED_MESSAGE =MainActivity.getContext().getString(R.string.SYNCHRONIZATION_FAILED_MESSAGE);// "Could not synchronize devices. Retry";
+
+    public static String PERFORMING_TASK_AS_HOST =MainActivity.getContext().getString(R.string.PERFORMING_TASK_AS_HOST);// "Acting as Host.";
+    public static String PERFORMING_TASK_AS_CLIENT = MainActivity.getContext().getString(R.string.PERFORMING_TASK_AS_CLIENT);//"Acting as Client.";
+
+    public static String ACTIONBAR_TITLE =MainActivity.getContext().getString(R.string.ACTIONBAR_TITLE);// "WifiDirect Synchronization";
+    public static String PROGRESS_TITLE_LOADING =MainActivity.getContext().getString(R.string.PROGRESS_TITLE_LOADING);// "Loading...";
+    public static String PROGRESS_TITLE_CONNECTING = MainActivity.getContext().getString(R.string.PROGRESS_TITLE_CONNECTING);//"Connecting...";
+
+    public static String DEVICE_STATUS_AVAILABLE =MainActivity.getContext().getString(R.string.DEVICE_STATUS_AVAILABLE);// "Available";
+    public static String DEVICE_STATUS_INVITED =MainActivity.getContext().getString(R.string.DEVICE_STATUS_INVITED);// "Invited";
+    public static String DEVICE_STATUS_CONNECTED = MainActivity.getContext().getString(R.string.DEVICE_STATUS_CONNECTED);//"Connected";
+    public static String DEVICE_STATUS_FAILED =MainActivity.getContext().getString(R.string.DEVICE_STATUS_FAILED);// "Failed";
+    public static String DEVICE_STATUS_UNAVAILABLE =MainActivity.getContext().getString(R.string.DEVICE_STATUS_UNAVAILABLE);// "Unavailable";
+    public static String DEVICE_STATUS_UNKNOWN =MainActivity.getContext().getString(R.string.DEVICE_STATUS_UNKNOWN);// "Unknown";
+
+    public static String WIFI_STATUS_DISABLED_MESSAGE =MainActivity.getContext().getString(R.string.WIFI_STATUS_DISABLED_MESSAGE);// "WiFi Direct down, please enable WiFi Direct";
+    public static String WIFI_STATUS_ENABLE_BUTTON = MainActivity.getContext().getString(R.string.WIFI_STATUS_ENABLE_BUTTON);//"Enable WiFi Direct";
+
+    public static String CANCEL_BUTTON_TITLE =MainActivity.getContext().getString(R.string.CANCEL_BUTTON_TITLE);// "Cancel";
+
+
     private SyncClientTask clientTask;
     private SyncHostTask  hostTask;
     private boolean isHost;
@@ -52,7 +83,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     private TextView mTxtP2PNotAvailable;
     private TextView mTxtP2PChangeDeviceName;
 
-    private WifiP2pDevice mDevice;
+    private WifiP2pDevice ownDevice;
     private WifiP2pDevice mOtherDevice;
 
     private ArrayList<WifiP2pDevice> discoveredDevices = new ArrayList<WifiP2pDevice>();
@@ -63,7 +94,6 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     public boolean isHost() {
         return isHost;
     }
-
     public void setHost(boolean isHost) {
         this.isHost = isHost;
     }
@@ -78,22 +108,26 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
         setContentView(R.layout.activity_p2_psync);
 
         assert getActionBar() != null;
-        getActionBar().setTitle("WifiDirect Synchronization");
+        getActionBar().setTitle(ACTIONBAR_TITLE);
 
         this.extractFromView();
         this.registerListeners();
 
+        this.wifiEventHandler().startService();
     }
 
     @Override
     public void onResume() {
         super.onResume();
-        this.wifiEventHandler().onResume();
+        this.wifiEventHandler().startService();
     }
 
     @Override
     public void onPause() {
-        this.wifiEventHandler().onPause();
+        if (this.clientTask != null) this.clientTask.interrupt(true);
+        if (this.hostTask != null) this.hostTask.interrupt(true);
+
+        this.wifiEventHandler().stopService();
         super.onPause();
     }
 
@@ -101,23 +135,32 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     protected void onStart()
     {
         super.onStart();
-        this.wifiEventHandler().onResume();
+        this.wifiEventHandler().startService();
     }
 
     @Override
     protected void onStop()
     {
+        if (this.clientTask != null) this.clientTask.interrupt(true);
+        if (this.hostTask != null) this.hostTask.interrupt(true);
         this.wifiEventHandler().disconnect();
-        this.wifiEventHandler().onPause();
+        this.wifiEventHandler().stopService();
         super.onStop();
     }
 
     @Override
     protected void onDestroy(){
-        this.wifiEventHandler().onPause();
+        if (this.clientTask != null) this.clientTask.interrupt(true);
+        if (this.hostTask != null) this.hostTask.interrupt(true);
+        this.wifiEventHandler().stopService();
         super.onDestroy();
     }
 
+    /**
+     * Returns a instance of the wifi event handler listener object. If no private instance was initiated it creates a new one.
+     * This object handles all gui changes.
+     * @return WiFiP2pEventHandler.WiFiP2pEventListener
+     */
     private WiFiP2pEventHandler.WiFiP2pEventListener eventListener(){
         if (_p2pEventListener == null){
             _p2pEventListener = new WiFiP2pEventHandler.WiFiP2pEventListener() {
@@ -143,7 +186,13 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
                 @Override
                 public void didConnect(boolean isHost, WifiP2pInfo connectionInfo) {
                     Log.d("WiFiP2pSyncActivity", "Did connect" + ".");
-                    this.activity.progressDialog = ProgressDialog.show(activity, "", "Loading...");
+
+                    String progressTitle = PROGRESS_TITLE_LOADING;
+                    if (this.activity.progressDialog != null){
+                        this.activity.progressDialog.dismiss();
+                    }
+                    this.activity.progressDialog = ProgressDialog.show(activity, "", progressTitle);
+
 
                     this.activity.setHost(isHost);
                     if (isHost){
@@ -158,7 +207,8 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
                 @Override
                 public void failedToConnect() {
                     Log.d("WiFiP2pSyncActivity", "Failed to connect" + ".");
-                    Toast.makeText(this.activity, "Could not connect to device. Retry.", Toast.LENGTH_LONG).show();
+                    Toast.makeText(this.activity, COULD_NOT_CONNECT_MESSAGE , Toast.LENGTH_LONG).show();
+                    this.activity.progressDialog.dismiss();
                 }
 
                 @Override
@@ -171,22 +221,35 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
                 public void failedToDisconnect() {
                     Log.d("WiFiP2pSyncActivity", "Failed to disconnect" + ".");
                     //Toast.makeText(this.activity, "Could not disconnect with device. Retry.", Toast.LENGTH_LONG).show();
+                    // Other device did disconnect a while before.
                     this.activity.progressDialog.dismiss();
                 }
 
                 @Override
-                public void deviceIsUpdated(WifiP2pDevice device) {
+                public void ownDeviceInformationIsUpdated(WifiP2pDevice device) {
                     Log.d("WiFiP2pSyncActivity", "Updated device " + device.deviceName + " " + device.deviceAddress + ".");
-                    this.activity.updateDevice(device);
+                    this.activity.updateOwnDeviceInformation(device);
                     this.activity.searchForDevices();
 
                 }
+
+                @Override
+                public void onConnectionLost() {
+                    Toast.makeText(this.activity, CONNECTION_LOST_MESSAGE , Toast.LENGTH_LONG).show();
+                    if (this.activity.progressDialog != null && this.activity.progressDialog.isShowing()){
+                        this.activity.progressDialog.dismiss();
+                    }
+                }
             }.init(this);
         }
 
         return _p2pEventListener;
     }
 
+    /**
+     * Returns a instance of the wifi event handler. If no private instance was initiated it creates a new one.
+     * @return WiFiP2pEventHandler
+     */
     private WiFiP2pEventHandler wifiEventHandler(){
         if (this._wifiEventHandler == null){
             this._wifiEventHandler = new WiFiP2pEventHandler(this, this.eventListener());
@@ -195,7 +258,10 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     }
 
 
-
+    /**
+     * Returns a sync completion listener. If no listener was initiated it creates a new on.
+     * @return BackgroundTaskCompletionListener
+     */
     private BackgroundTask.BackgroundTaskCompletionListener syncCompletionListener(){
         if (_syncCompletionListener == null){
             _syncCompletionListener = new BackgroundTask.BackgroundTaskCompletionListener() {
@@ -206,34 +272,14 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
                 }
                 @Override
                 public void didSucceed() {
-                    this.activity.runOnUiThread(new Runnable() {
-                        private WiFiP2pSyncActivity activity;
-                        @Override
-                        public void run() {
-                            Toast.makeText(this.activity, "Synchronization complete.", Toast.LENGTH_SHORT).show();
-                            this.activity.wifiEventHandler().disconnect();
-                        }
-                        public Runnable init(WiFiP2pSyncActivity activity){
-                            this.activity = activity;
-                            return this;
-                        }
-                    }.init(this.activity));
+                    Toast.makeText(this.activity, SYNCHRONIZATION_COMPLETE_MESSAGE , Toast.LENGTH_SHORT).show();
+                    this.activity.wifiEventHandler().disconnect();
                 }
 
                 @Override
                 public void didFail() {
-                    this.activity.runOnUiThread(new Runnable() {
-                        private WiFiP2pSyncActivity activity;
-                        @Override
-                        public void run() {
-                            Toast.makeText(this.activity, "Could not synchronize with device. Retry.", Toast.LENGTH_LONG).show();
-                            this.activity.wifiEventHandler().disconnect();
-                        }
-                        public Runnable init(WiFiP2pSyncActivity activity){
-                            this.activity = activity;
-                            return this;
-                        }
-                    }.init(this.activity));
+                    Toast.makeText(this.activity, SYNCHRONIZATION_FAILED_MESSAGE, Toast.LENGTH_LONG).show();
+                    this.activity.wifiEventHandler().disconnect();
                 }
             }.init(this);
         }
@@ -241,13 +287,20 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     }
 
 
-    private void updateDeviceListView(List<WifiP2pDevice> peers){
+    /**
+     * Updates the device list on the ui thread.
+     * @param peers
+     */
+    private void updateDeviceListView(List<WifiP2pDevice> peers)
+    {
         mTxtP2PSearchProgress.setVisibility(View.GONE);
 
         this.discoveredDevices = new ArrayList<WifiP2pDevice>();
         this.discoveredDevices.addAll(peers);
         WiFiPeerListAdapter listAdapter = (WiFiPeerListAdapter) this.mLstP2PDevices.getAdapter();
         listAdapter.addItems(peers);
+
+        // Run the update process on the gui thread, otherwise the list wont be updated.
         this.runOnUiThread(new Runnable() {
             private ListView listView;
 
@@ -265,47 +318,88 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
             }
         }.init(this.mLstP2PDevices));
         Log.d("WiFiP2pSyncActivity", " Discovered "+peers.size()+" devices.");
+
+        if (peers.size() == 0){
+            this.searchForDevices();
+        }
     }
 
-    private void startHost(){
+    /**
+     * Starts the Host task. Informs the user by a little toast.
+     */
+    private void startHost()
+    {
         Log.d("WiFiP2pSyncActivity", "Starting HOST Task" + ".");
-        Toast.makeText(this, "Acting as Host.", Toast.LENGTH_SHORT).show();
-        this.hostTask = new SyncHostTask(this.syncCompletionListener(), getApplicationContext());
+        //Toast.makeText(this, PERFORMING_TASK_AS_HOST , Toast.LENGTH_SHORT).show();
+        this.hostTask = new SyncHostTask(this.ownDevice, this.syncCompletionListener(), getApplicationContext());
         this.hostTask.execute();
     }
 
-    private void startClient(WifiP2pInfo info){
+    /**
+     * Starts the wifi direct client task. Informs the user by a little toast.
+     * @param info the WifiP2pInfo contains the groupOwnerAddress which is needed for the client task.
+     */
+    private void startClient(WifiP2pInfo info)
+    {
         Log.d("WiFiP2pSyncActivity", "Starting CLIENT Task" + ".");
-        Toast.makeText(this, "Acting as Client.", Toast.LENGTH_SHORT).show();
-        this.clientTask = new SyncClientTask(info.groupOwnerAddress.getHostAddress(), this.syncCompletionListener(), getApplicationContext() );
+        //Toast.makeText(this, PERFORMING_TASK_AS_CLIENT, Toast.LENGTH_SHORT).show();
+        this.clientTask = new SyncClientTask( info.groupOwnerAddress.getHostAddress(),this.ownDevice, this.syncCompletionListener(), getApplicationContext() );
         this.clientTask.execute();
     }
 
+    /**
+     * Try to connect to the given device and shows a simple progress dialog.
+     * @param device
+     */
+    private void connectTo(WifiP2pDevice device){
+        String connectionTitle = PROGRESS_TITLE_CONNECTING;
+        if (device != null){
+            if (progressDialog == null){
+                this.progressDialog = ProgressDialog.show(this, "", connectionTitle);
+            } else {
+                progressDialog.setTitle(connectionTitle);
+            }
+            mOtherDevice = device;
+            this.wifiEventHandler().connect(device);
+        }
+    }
 
+    /**
+     * Returns a localized device status string.
+     * @param deviceStatus the status to convert.
+     * @return status string
+     */
     private static String getDeviceStatus(int deviceStatus) {
         switch (deviceStatus) {
             case WifiP2pDevice.AVAILABLE:
-                return "Available";
+                return DEVICE_STATUS_AVAILABLE;
             case WifiP2pDevice.INVITED:
-                return "Invited";
+                return DEVICE_STATUS_INVITED;
             case WifiP2pDevice.CONNECTED:
-                return "Connected";
+                return DEVICE_STATUS_CONNECTED;
             case WifiP2pDevice.FAILED:
-                return "Failed";
+                return DEVICE_STATUS_FAILED;
             case WifiP2pDevice.UNAVAILABLE:
-                return "Unavailable";
+                return DEVICE_STATUS_UNAVAILABLE;
             default:
-                return "Unknown";
+                return DEVICE_STATUS_UNKNOWN;
         }
     }
 
-
-    private void updateDevice(WifiP2pDevice device){
+    /**
+     * Updates / displays own device information.
+     * @param device
+     */
+    private void updateOwnDeviceInformation(WifiP2pDevice device)
+    {
         mTxtP2PDeviceName.setText(device.deviceName);
         mTxtP2PDeviceStatus.setText(getDeviceStatus(device.status));
-        mDevice = device;
+        ownDevice = device;
     }
 
+    /**
+     * Method to search for new devices.
+     */
     private void searchForDevices(){
         mTxtP2PSearchProgress.setVisibility(View.VISIBLE);
         this.wifiEventHandler().discoverDevices();
@@ -313,22 +407,50 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
 
     /********************** UI ************************/
 
-
+    /**
+     * Informs the user about a changed wifi state.
+     * enabled = true - mTxtP2PNotAvailable is gone
+     * enabled = false - mTxtP2PNotAvailable stays and a alert box is displayed for a quick navigation to the wifi settings.
+     * @param enabled
+     */
     public void setWifiDirectAvailable(boolean enabled){
         if (enabled){
             mTxtP2PNotAvailable.setVisibility(View.GONE);
         } else {
             mTxtP2PNotAvailable.setVisibility(View.VISIBLE);
             ((WiFiPeerListAdapter) mLstP2PDevices.getAdapter()).notifyDataSetChanged();
-            mDevice = null;
+            ownDevice = null;
             this.updateDeviceListView(new ArrayList<WifiP2pDevice>());
-
-            Toast.makeText(this, "WiFi Direct P2P is disabled.", Toast.LENGTH_LONG).show();
+            this.showWifiDisabledDialog();
+            //Toast.makeText(this, "WiFi Direct P2P is disabled.", Toast.LENGTH_LONG).show();
         }
     }
 
+    /**
+     * Displays a AlertDialog that informs the User about the disabled Wifi state and can navigate the user directly to the wifi settings.
+     */
+    private void showWifiDisabledDialog(){
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setMessage(WIFI_STATUS_DISABLED_MESSAGE)
+                .setCancelable(true)
+                .setPositiveButton(WIFI_STATUS_ENABLE_BUTTON, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+                    }
+                })
+                .setNegativeButton(CANCEL_BUTTON_TITLE, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        finish();
+                    }
+                });
 
+        AlertDialog info = builder.create();
+        info.show();
+    }
 
+    /**
+     * Extracts all subview initially from the view hierarchy.
+     */
     private void extractFromView(){
         this.mTxtP2PDeviceName = (TextView) findViewById(R.id.txt_p2p_device_name);
         this.mTxtP2PDeviceStatus = (TextView) findViewById(R.id.txt_p2p_device_status);
@@ -342,25 +464,10 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
         this.mTxtP2PNotAvailable = (TextView) findViewById(R.id.txtP2PNotAvailable);
     }
 
+    /**
+     * Registers all the gui listeners.
+     */
     public void registerListeners(){
-        /*
-        mTxtP2PChangeDeviceName.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                Method method1 = null;
-                try {
-                    method1 = mManager.getClass().getDeclaredMethod("setDeviceName", WifiP2pManager.Channel.class);
-                    method1.invoke(mManager, mChannel, "Android_fc546");
-                } catch (NoSuchMethodException e) {
-                    e.printStackTrace();
-                } catch (InvocationTargetException e) {
-                    e.printStackTrace();
-                } catch (IllegalAccessException e) {
-                    e.printStackTrace();
-                }
-            }
-        });*/
-
         if (this.mLstP2PDevices.getOnItemClickListener() != this)
             this.mLstP2PDevices.setOnItemClickListener(this);
 
@@ -375,8 +482,7 @@ public class WiFiP2pSyncActivity extends Activity implements AdapterView.OnItemC
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         final WifiP2pDevice device = (WifiP2pDevice) this.mLstP2PDevices.getAdapter().getItem(position);
-        this.wifiEventHandler().connect(device);
-        mOtherDevice = device;
+        this.connectTo(device);
     }