diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 665b551..5cd0755 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -4,27 +4,18 @@
-
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 2bfae1d..e1f0009 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -62,6 +62,7 @@ dependencies {
implementation("androidx.compose.material3:material3")
implementation("androidx.room:room-ktx:2.6.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
+ implementation("androidx.navigation:navigation-compose:2.7.7")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6780e64..4dad71a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
diff --git a/app/src/main/java/com/faraphel/tasks_valider/MainActivity.kt b/app/src/main/java/com/faraphel/tasks_valider/MainActivity.kt
index 56cbc1c..b3ef37d 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/MainActivity.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/MainActivity.kt
@@ -1,25 +1,24 @@
package com.faraphel.tasks_valider
-import android.content.Context
-import android.content.pm.PackageManager
import android.Manifest
import android.annotation.SuppressLint
-import android.net.wifi.p2p.*
+import android.content.Context
+import android.content.pm.PackageManager
+import android.net.wifi.p2p.WifiP2pManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.RequiresApi
-import com.faraphel.tasks_valider.connectivity.packets.PacketPing
-import com.faraphel.tasks_valider.connectivity.wifi_p2p.WifiP2pHelper
+import com.faraphel.tasks_valider.connectivity.bwf.BwfManager
+import com.faraphel.tasks_valider.connectivity.bwf.error.BwfNotSupportedException
import com.faraphel.tasks_valider.database.Database
import com.faraphel.tasks_valider.ui.screen.room.RoomScreen
class MainActivity : ComponentActivity() {
- private var PERMISSION_ACCESS_FINE_LOCATION = 1001 ///< permission code for the fi
- private var p2pHelper: WifiP2pHelper? = null ///< the Wi-Fi Direct helper
+ private var bwfManager: BwfManager? = null ///< the WiFi-Direct helper
companion object {
private lateinit var database: Database ///< the database manager
@@ -29,56 +28,56 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- // ----- CONNECTION
+ // TODO(Faraphel): more check on permissions
- // TOOD: more check on permissions
+ // check if the system support WiFi-Direct
if (!this.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
Log.e("wifi-p2p", "this device does not support the WiFi-Direct feature")
- return
+ throw BwfNotSupportedException()
}
- if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ if (
+ this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
+ this.checkSelfPermission(Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED
+ ) {
// TODO(Faraphel): should be used with shouldShowRequestPermissionRationale, with a check
- this.requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_ACCESS_FINE_LOCATION)
+ this.requestPermissions(
+ arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
+ BwfManager.PERMISSION_ACCESS_FINE_LOCATION
+ )
}
// get the WiFi-Direct manager
- val p2pManager: WifiP2pManager? = this.getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager?
- if (p2pManager == null) {
+ val manager = this.getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager?
+ if (manager == null) {
Log.e("wifi-p2p", "cannot access the WiFi-Direct manager")
- return
+ throw BwfNotSupportedException()
}
- // get the Wifi-Direct channel
- val p2pChannel: WifiP2pManager.Channel = p2pManager.initialize(this, this.mainLooper, null)
+ // create a channel for the manager
+ val channel = manager.initialize(this, this.mainLooper, null)
- // create a helper for handling the WiFi-Direct
- this.p2pHelper = WifiP2pHelper(p2pManager, p2pChannel)
+ // create a new manager for handling the WiFi-Direct
+ this.bwfManager = BwfManager(manager, channel)
// open the room selection screen
this.setContent {
- RoomScreen(this.p2pHelper!!)
+ RoomScreen(this.bwfManager!!)
}
}
- @RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("UnspecifiedRegisterReceiverFlag")
override fun onResume() {
super.onResume()
// enable the WiFi-Direct events
- this.registerReceiver(this.p2pHelper, WifiP2pHelper.ALL_INTENT_FILTER)
+ this.registerReceiver(this.bwfManager, BwfManager.ALL_INTENT_FILTER)
}
override fun onPause() {
super.onPause()
// disable the WiFi-Direct events
- this.unregisterReceiver(this.p2pHelper)
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- super.onSaveInstanceState(outState)
- // TODO(Faraphel): save the current state to reload it later
+ this.unregisterReceiver(this.bwfManager)
}
}
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/BwfManager.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/BwfManager.kt
new file mode 100644
index 0000000..19780b3
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/BwfManager.kt
@@ -0,0 +1,151 @@
+package com.faraphel.tasks_valider.connectivity.bwf
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.net.wifi.p2p.*
+import androidx.compose.runtime.mutableStateOf
+import com.faraphel.tasks_valider.connectivity.bwf.error.*
+
+
+/**
+ * A helper to wrap the WiFi-Direct manager, the channel and the events.
+ *
+ * This avoids certain annoying features such as always specifying the channel as the first argument or
+ * handling all the events with the base event system.
+ *
+ * @param manager The WiFi-Direct manager
+ * @param channel The WiFi-Direct channel
+ */
+class BwfManager(
+ private var manager: WifiP2pManager,
+ private var channel: WifiP2pManager.Channel,
+) : BroadcastReceiver() {
+ companion object {
+ var PERMISSION_ACCESS_FINE_LOCATION = 1001 ///< permission code for the fine location
+ var ALL_INTENT_FILTER = IntentFilter().apply {
+ addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
+ addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)
+ }
+ }
+
+ // Wrappers
+
+ /**
+ * Connect to another device, allowing for a communication using Sockets
+ * @see WifiP2pManager.connect
+ * @throws SecurityException if the permission has not been given
+ */
+ @Throws(SecurityException::class)
+ fun connect(config: WifiP2pConfig, callback: () -> Unit = {}) =
+ this.manager.connect(this.channel, config, object : WifiP2pManager.ActionListener {
+ override fun onSuccess() { callback() }
+ override fun onFailure(reason: Int) = throw BwfConnectException(reason)
+ })
+
+ /**
+ * Request the list of peers after a discovery.
+ * @see WifiP2pManager.requestPeers
+ * @throws SecurityException if the permission has not been given
+ */
+ @Throws(SecurityException::class)
+ fun requestPeers(callback: (WifiP2pDeviceList) -> Unit = {}) =
+ this.manager.requestPeers(this.channel, callback)
+
+ /**
+ * Start discovering peers.
+ * Once founds, the WIFI_P2P_PEERS_CHANGED_ACTION event will be triggered.
+ * @see WifiP2pManager.discoverPeers
+ * @throws SecurityException if the permission has not been given
+ */
+ @Throws(SecurityException::class)
+ fun discoverPeers(callback: () -> Unit = {}) =
+ this.manager.discoverPeers(this.channel, object : WifiP2pManager.ActionListener {
+ override fun onSuccess() { callback() }
+ override fun onFailure(reason: Int) = throw BwfDiscoverException(reason)
+ })
+
+ /**
+ * Obtain information about a connection with another device.
+ * @see WifiP2pManager.requestConnectionInfo
+ */
+ fun requestConnectionInfo(callback: (WifiP2pInfo) -> Unit = {}) =
+ this.manager.requestConnectionInfo(this.channel, callback)
+
+ /**
+ * Obtain information about the current group.
+ * @see WifiP2pManager.requestGroupInfo
+ * @throws SecurityException if the permission has not been given
+ */
+ @Throws(SecurityException::class)
+ fun requestGroupInfo(callback: (WifiP2pGroup?) -> Unit = {}) =
+ this.manager.requestGroupInfo(this.channel, callback)
+
+ /**
+ * Create a new WiFi-Direct group.
+ * @see WifiP2pManager.createGroup
+ * @throws SecurityException if the permission has not been given
+ */
+ @Throws(SecurityException::class)
+ fun createGroup(callback: () -> Unit = {}) =
+ this.manager.createGroup(this.channel, object : WifiP2pManager.ActionListener {
+ override fun onSuccess() { callback() }
+ override fun onFailure(reason: Int) = throw BwfCreateGroupException(reason)
+ })
+
+ /**
+ * Disconnect from the current WiFi-Direct group.
+ * @see WifiP2pManager.removeGroup
+ */
+ fun removeGroup(callback: () -> Unit = {}) =
+ this.manager.removeGroup(this.channel, object : WifiP2pManager.ActionListener {
+ override fun onSuccess() { callback() }
+ override fun onFailure(reason: Int) = throw BwfRemoveGroupException(reason)
+ })
+
+ /**
+ * Create a new WiFi-Direct group. If already connected to a group, quit it first.
+ *
+ * Note: most of the failure on removal are caused by not having a group already created, which is checked.
+ *
+ * @param listener: the createGroup listener
+ * @param onRemoveFailure: error handler for the removeGroup event
+ *
+ * @see WifiP2pManager.createGroup
+ * @see WifiP2pManager.removeGroup
+ */
+ fun recreateGroup(callback: () -> Unit = {}) {
+ // get the current group information
+ this.requestGroupInfo { group ->
+ // if a group exist, quit it
+ if (group != null)
+ this.removeGroup { this@BwfManager.createGroup(callback) }
+ else
+ // create the group
+ this.createGroup(callback)
+ }
+ }
+
+ // Events
+
+ val stateConnectionInfo = mutableStateOf(null)
+ val statePeers = mutableStateOf(null)
+
+ override fun onReceive(context: Context?, intent: Intent?) {
+ // ignore empty intent
+ if (intent == null)
+ return
+
+ // update the action corresponding state
+ when (intent.action) {
+ WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> this.requestConnectionInfo {
+ connectionInfo -> stateConnectionInfo.value = connectionInfo
+ }
+ WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> this.requestPeers {
+ peers -> statePeers.value = peers
+ }
+ }
+ // TODO(Faraphel): implement event dispatcher
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/README.md b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/README.md
new file mode 100644
index 0000000..4e0acc5
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/README.md
@@ -0,0 +1,11 @@
+# Better WiFi-Direct (BWD)
+
+This package contain code to improve the base WiFi-Direct implementation.
+
+The base have some issue, like an abusive usage of listener, error code and events that make using it
+very impractical.
+
+This improved version will instead focus on asynchronous function and exception, allowing for a
+cleaner linear code instead.
+
+(Author: https://git.faraphel.fr/Faraphel)
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfConnectException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfConnectException.kt
new file mode 100644
index 0000000..a581c09
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfConnectException.kt
@@ -0,0 +1,5 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfConnectException(
+ reason: Int
+) : BwfException("Cannot connect to the peer. Reason: $reason")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfCreateGroupException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfCreateGroupException.kt
new file mode 100644
index 0000000..0ce1169
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfCreateGroupException.kt
@@ -0,0 +1,5 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfCreateGroupException (
+ reason: Int
+) : BwfException("Could not create the group : $reason")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfDiscoverException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfDiscoverException.kt
new file mode 100644
index 0000000..a4e818a
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfDiscoverException.kt
@@ -0,0 +1,5 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfDiscoverException(
+ reason: Int
+) : BwfException("Could not discover peers : $reason")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfException.kt
similarity index 57%
rename from app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperException.kt
rename to app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfException.kt
index 892e2b2..7fd8810 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperException.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfException.kt
@@ -1,9 +1,9 @@
-package com.faraphel.tasks_valider.connectivity.wifi_p2p.error
+package com.faraphel.tasks_valider.connectivity.bwf.error
/**
* Base Exception for everything concerning the WifiP2pHelper class
*/
-open class WifiP2pHelperException(
+open class BwfException(
override val message: String?
) : Exception(message)
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfInvalidActionException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfInvalidActionException.kt
new file mode 100644
index 0000000..0b690a3
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfInvalidActionException.kt
@@ -0,0 +1,5 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfInvalidActionException(
+ action: String
+) : BwfException("This WiFi-Direct action is not supported : $action")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfNotSupportedException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfNotSupportedException.kt
new file mode 100644
index 0000000..9f11424
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfNotSupportedException.kt
@@ -0,0 +1,4 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfNotSupportedException :
+ BwfException("WiFi-Direct is not supported on this device, or it is disabled.")
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfRemoveGroupException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfRemoveGroupException.kt
new file mode 100644
index 0000000..92d0789
--- /dev/null
+++ b/app/src/main/java/com/faraphel/tasks_valider/connectivity/bwf/error/BwfRemoveGroupException.kt
@@ -0,0 +1,5 @@
+package com.faraphel.tasks_valider.connectivity.bwf.error
+
+class BwfRemoveGroupException (
+ reason: Int
+) : BwfException("Could not remove the group : $reason")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelper.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelper.kt
deleted file mode 100644
index 574a030..0000000
--- a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelper.kt
+++ /dev/null
@@ -1,212 +0,0 @@
-package com.faraphel.tasks_valider.connectivity.wifi_p2p
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.net.wifi.p2p.WifiP2pConfig
-import android.net.wifi.p2p.WifiP2pDeviceList
-import android.net.wifi.p2p.WifiP2pManager
-import android.os.Build
-import android.util.Log
-import androidx.annotation.RequiresApi
-import com.faraphel.tasks_valider.connectivity.wifi_p2p.error.WifiP2pHelperInvalidActionException
-
-
-/**
- * A helper to wrap the WiFi-Direct manager, the channel and the events.
- *
- * This avoids certain annoying features such as always specifying the channel as the first argument or
- * handling all the events with the base event system.
- *
- * @param manager: the WiFi-Direct base manager
- * @param channel: the WiFi-Direct channel
- */
-class WifiP2pHelper(
- private val manager: WifiP2pManager,
- private val channel: WifiP2pManager.Channel,
-) : BroadcastReceiver() {
- companion object {
- /**
- * This IntentFilter can be used to subscribe the helper to every supported WiFi-Direct events.
- */
- val ALL_INTENT_FILTER = IntentFilter().apply {
- addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)
- addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)
- addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
- addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)
- }
- }
-
- // Events
-
- /**
- * Contains the listeners to call when the peers are updated.
- */
- private val listenersPeersChanged = mutableListOf Unit>>()
-
- /**
- * Event receiver for the WiFi-Direct events.
- * Should not be called manually.
- * @param context: the WiFi-Direct context
- * @param intent: the event information
- */
- @RequiresApi(Build.VERSION_CODES.N)
- override fun onReceive(context: Context, intent: Intent) {
- when (intent.action) {
- WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> {
- Log.v("wifi-p2p", "Connection Changed : $context, $intent, ${intent.extras}")
- }
-
- WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> {
- Log.v("wifi-p2p", "Peers Changed : $context, $intent, ${intent.extras}")
-
- this.requestPeers { peers ->
- this@WifiP2pHelper.listenersPeersChanged.forEach { listenerInfo -> listenerInfo.callback(peers) }
- this@WifiP2pHelper.listenersPeersChanged.removeIf { listenerInfo -> listenerInfo.once }
- }
- }
-
- WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION -> {
- Log.v("wifi-p2p", "State Changed : $context, $intent, ${intent.extras}")
- }
-
- WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> {
- Log.v("wifi-p2p", "This Device Changed : $context, $intent, ${intent.extras}")
- }
- }
- }
-
- /**
- * Register a listener to a specific WiFi-Direct event.
- * @param action: the name of the WiFi-Direct event
- * @param callback: the callback function
- * @param once: should the event be only called once ?
- */
- fun registerListener(action: String, callback: CallbackType, once: Boolean = false) {
- when (action) {
- WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> {
- @Suppress("UNCHECKED_CAST")
- this.listenersPeersChanged.add(WifiP2pHelperListenerInfo(
- callback as ((WifiP2pDeviceList?) -> Unit),
- once
- ))
- }
- else -> {
- // raise an exception if the action is invalid
- throw WifiP2pHelperInvalidActionException(action)
- }
- }
- }
-
- @RequiresApi(Build.VERSION_CODES.N)
- fun unregisterListener(action: String, callback: CallbackType) {
- when (action) {
- WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> {
- this.listenersPeersChanged.removeIf { listenerInfo -> listenerInfo.callback == callback }
- }
- else -> {
- // raise an exception if the action is invalid
- throw WifiP2pHelperInvalidActionException(action)
- }
- }
- }
-
- // Wrappers
-
- /**
- * Connect to another device, allowing for a communication using Sockets
- * @see WifiP2pManager.connect
- */
- fun connect(config: WifiP2pConfig, listener: WifiP2pManager.ActionListener? = null) {
- this.manager.connect(this.channel, config, listener)
- }
-
- /**
- * Request the list of peers after a discovery.
- * @see WifiP2pManager.requestPeers
- */
- fun requestPeers(listener: WifiP2pManager.PeerListListener? = null) {
- this.manager.requestPeers(this.channel, listener)
- }
-
- /**
- * Start discovering peers.
- * Once founds, the WIFI_P2P_PEERS_CHANGED_ACTION event will be triggered.
- * @see WifiP2pManager.discoverPeers
- */
- fun discoverPeers(listener: WifiP2pManager.ActionListener? = null) {
- this.manager.discoverPeers(this.channel, listener)
- }
-
- /**
- * Obtain information about a connection with another device.
- * @see WifiP2pManager.requestConnectionInfo
- */
- fun requestConnectionInfo(listener: WifiP2pManager.ConnectionInfoListener? = null) {
- this.manager.requestConnectionInfo(this.channel, listener)
- }
-
- /**
- * Obtain information about the current group.
- * @see WifiP2pManager.requestGroupInfo
- */
- fun requestGroupInfo(listener: WifiP2pManager.GroupInfoListener? = null) {
- this.manager.requestGroupInfo(this.channel, listener)
- }
-
- /**
- * Create a new WiFi-Direct group.
- * @see WifiP2pManager.createGroup
- */
- fun createGroup(listener: WifiP2pManager.ActionListener? = null) {
- this.manager.createGroup(this.channel, listener)
- }
-
- /**
- * Disconnect from the current WiFi-Direct group.
- * @see WifiP2pManager.removeGroup
- */
- fun removeGroup(listener: WifiP2pManager.ActionListener? = null) {
- this.manager.removeGroup(this.channel, listener)
- }
-
- // Shortcuts
-
- /**
- * Create a new WiFi-Direct group. If already connected to a group, quit it first.
- *
- * Note: most of the failure on removal are caused by not having a group already created, which is checked.
- *
- * @param listener: the createGroup listener
- * @param onRemoveFailure: error handler for the removeGroup event
- *
- * @see WifiP2pManager.createGroup
- * @see WifiP2pManager.removeGroup
- */
- fun recreateGroup(
- listener: WifiP2pManager.ActionListener? = null,
- onRemoveFailure: ((Int) -> Unit)? = null
- ) {
- // get the current group information
- this.requestGroupInfo { group ->
- // if a group exist, quit it
- if (group != null)
- this.removeGroup(object : WifiP2pManager.ActionListener {
- override fun onSuccess() {
- // once left, create the group
- this@WifiP2pHelper.createGroup(listener)
- }
-
- override fun onFailure(reason: Int) {
- // call the handler
- onRemoveFailure?.invoke(reason)
- }
-
- })
- else
- // create the group
- this.createGroup(listener)
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelperListenerInfo.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelperListenerInfo.kt
deleted file mode 100644
index 3c68903..0000000
--- a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/WifiP2pHelperListenerInfo.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.faraphel.tasks_valider.connectivity.wifi_p2p
-
-import java.util.concurrent.Callable
-
-
-/**
- * This class contain the information required to store a listener in the WifiP2pHelper class to correctly handle events.
- * @param CallbackType: the type of the callback function
- * @param callback: the function to call when the event is triggered
- * @param once: should the listener be called only once ?
- */
-class WifiP2pHelperListenerInfo(
- val callback: CallbackType,
- val once: Boolean,
-)
diff --git a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperInvalidActionException.kt b/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperInvalidActionException.kt
deleted file mode 100644
index 26d147f..0000000
--- a/app/src/main/java/com/faraphel/tasks_valider/connectivity/wifi_p2p/error/WifiP2pHelperInvalidActionException.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.faraphel.tasks_valider.connectivity.wifi_p2p.error
-
-class WifiP2pHelperInvalidActionException(
- action: String
-) : WifiP2pHelperException("This WiFi-Direct action is not supported : $action")
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomClientScreen.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomClientScreen.kt
index 681d4c8..44b1b0b 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomClientScreen.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomClientScreen.kt
@@ -3,32 +3,50 @@ package com.faraphel.tasks_valider.ui.screen.room
import android.net.wifi.p2p.WifiP2pConfig
import android.net.wifi.p2p.WifiP2pDevice
import android.net.wifi.p2p.WifiP2pDeviceList
-import android.net.wifi.p2p.WifiP2pInfo
-import android.net.wifi.p2p.WifiP2pManager
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import com.faraphel.tasks_valider.connectivity.bwf.BwfManager
import com.faraphel.tasks_valider.connectivity.room.RoomClient
-import com.faraphel.tasks_valider.connectivity.wifi_p2p.WifiP2pHelper
import com.faraphel.tasks_valider.ui.screen.tasks.TaskGroupScreen
import com.faraphel.tasks_valider.ui.widgets.connectivity.WifiP2pDeviceListWidget
+import kotlinx.coroutines.runBlocking
/**
* This screen allow the user to join a room
*/
@Composable
-fun RoomClientScreen(wifiP2pHelper: WifiP2pHelper) {
- val peers = remember { mutableStateOf(null) }
+fun RoomClientScreen(bwfManager: BwfManager) {
+ val navController = rememberNavController()
+
val selectedDevice = remember { mutableStateOf(null) }
val connected = remember { mutableStateOf(false) }
- // if the device is connected to a host, display the main screen
- if (connected.value) {
- TaskGroupScreen()
+ NavHost(navController = navController, startDestination = "roomSearch") {
+ composable(route = "roomSearch") {
+ // let the user pick which host he wishes to connect to
+ Column {
+ Text(text = "Find a Server")
+ // display all the devices that are owner of their group
+ WifiP2pDeviceListWidget(
+ peers = bwfManager.statePeers.value,
+ filter = { device: WifiP2pDevice -> device.isGroupOwner },
+ selectedDevice,
+ )
+ }
+
+ // update the list when a new device is detected
+ }
+ composable(route = "taskGroup") {
+ TaskGroupScreen()
+ }
}
// if a device is selected, connect to it
@@ -37,53 +55,17 @@ fun RoomClientScreen(wifiP2pHelper: WifiP2pHelper) {
val config = WifiP2pConfig().apply {
deviceAddress = selectedDevice.value!!.deviceAddress
}
- // try to connect
- wifiP2pHelper.connect(config, object : WifiP2pManager.ActionListener {
- override fun onSuccess() {
- Log.i("room", "Connection successful to the host !")
- // request additional information about the connection to obtain the host IP
- wifiP2pHelper.registerListener(
- WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION,
- { connectionInfo: WifiP2pInfo ->
- val client = RoomClient(
- connectionInfo.groupOwnerAddress,
- 9876 // TODO(Faraphel): port should be a settings
- )
- Thread {
- client.start()
- }.start()
- connected.value = true
- },
- once = true
- )
+ // try to connect to the host
+ bwfManager.connect(config) {
+ Log.i("room", "Connection successful to the host !")
+
+ bwfManager.requestConnectionInfo { connectionInfo ->
+ val client = RoomClient(connectionInfo.groupOwnerAddress, 9876) // TODO(Faraphel): port should be a settings
+ Thread { client.start() }.start()
+
+ connected.value = true
}
-
- override fun onFailure(reason: Int) {
- // TODO(Faraphel): for most of theses messages, shouldn't a toast be used instead ?
- Log.e("room", "Could not connect to this host. Reason: $reason")
- }
- })
- return
+ }
}
-
- // let the user pick which host he wishes to connect to
-
- Column {
- Text(text = "Find a Server")
- // display all the devices that are owner of their group
- WifiP2pDeviceListWidget(
- peers = peers.value,
- filter = { device: WifiP2pDevice -> device.isGroupOwner },
- selectedDevice,
- )
- }
-
- // TODO(Faraphel): might be doubtful. Test with more phones, should it only run once ? refresh button ?
- // update the list when a new device is detected
- wifiP2pHelper.registerListener(
- WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION,
- { newPeers: WifiP2pDeviceList? -> peers.value = newPeers },
- )
- wifiP2pHelper.discoverPeers()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomHostScreen.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomHostScreen.kt
index 467470b..bb9ba87 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomHostScreen.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomHostScreen.kt
@@ -1,6 +1,5 @@
package com.faraphel.tasks_valider.ui.screen.room
-import android.net.wifi.p2p.WifiP2pManager
import android.util.Log
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
@@ -10,8 +9,9 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
-import com.faraphel.tasks_valider.connectivity.wifi_p2p.WifiP2pHelper
+import com.faraphel.tasks_valider.connectivity.bwf.BwfManager
import com.faraphel.tasks_valider.ui.screen.tasks.TaskGroupScreen
+import kotlinx.coroutines.runBlocking
import java.net.ServerSocket
@@ -22,7 +22,7 @@ var DEFAULT_SERVER_PORT: Int = 9876
* This screen allow the user to create a room
*/
@Composable
-fun RoomHostScreen(wifiP2pHelper: WifiP2pHelper) {
+fun RoomHostScreen(bwfManager: BwfManager) {
val expanded = remember { mutableStateOf(false) }
val serverPort = remember { mutableStateOf(DEFAULT_SERVER_PORT) }
val isCreated = remember { mutableStateOf(false) }
@@ -65,23 +65,19 @@ fun RoomHostScreen(wifiP2pHelper: WifiP2pHelper) {
Button(onClick = {
// create a new WiFi-Direct group
- wifiP2pHelper.recreateGroup(object : WifiP2pManager.ActionListener {
- override fun onSuccess() {
- Log.i("room", "group created !")
+ bwfManager.recreateGroup {
+ Log.i("room", "group created !")
- val server = ServerSocket(serverPort.value) // TODO(Faraphel): should the port be a settings ?
- Thread {
- val client = server.accept() // TODO(Faraphel): should run in a thread
- client.getInputStream()
- }
+ // open a new server
+ val server = ServerSocket(serverPort.value)
+ Thread {
+ val client = server.accept() // TODO(Faraphel): should run in a thread
+ client.getInputStream()
+ }
- // mark the group as created
- isCreated.value = true
- }
- override fun onFailure(reason: Int) {
- Log.e("room", "error while creating group. Reason: $reason")
- }
- })
+ // mark the group as created
+ isCreated.value = true
+ }
}) {
Text("Create")
}
diff --git a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomScreen.kt b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomScreen.kt
index 3e7b38a..efa95bd 100644
--- a/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomScreen.kt
+++ b/app/src/main/java/com/faraphel/tasks_valider/ui/screen/room/RoomScreen.kt
@@ -6,42 +6,35 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import com.faraphel.tasks_valider.connectivity.wifi_p2p.WifiP2pHelper
-
-
-enum class RoomScreenType {
- HOST,
- CLIENT
-}
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import com.faraphel.tasks_valider.connectivity.bwf.BwfManager
/**
* This screen will allow the user to choose which room is he connecting to, or let him create one.
*/
@Composable
-fun RoomScreen(wifiP2pHelper: WifiP2pHelper) {
- val roomMode = remember { mutableStateOf(null) }
+fun RoomScreen(bwfManager: BwfManager) {
+ val navController = rememberNavController()
- when (roomMode.value) {
- RoomScreenType.CLIENT -> {
- // Client mode
- RoomClientScreen(wifiP2pHelper)
- }
- RoomScreenType.HOST -> {
- // Host mode
- RoomHostScreen(wifiP2pHelper)
- }
-
- null -> {
- // let the user decide which room mode he which to use
+ NavHost(navController = navController, startDestination = "pickMode") {
+ composable(route = "pickMode") {
Column {
- Button(onClick = { roomMode.value = RoomScreenType.CLIENT }) {
+ Button(onClick = { navController.navigate("client") }) {
Text(text = "Join a room")
}
- Button(onClick = { roomMode.value = RoomScreenType.HOST }) {
+ Button(onClick = { navController.navigate("host") }) {
Text(text = "Create a room")
}
}
}
+ composable(route = "client") {
+ RoomClientScreen(bwfManager)
+ }
+ composable(route = "host") {
+ RoomHostScreen(bwfManager)
+ }
}
}
\ No newline at end of file