fixed the Wi-Fi direct server creation

This commit is contained in:
Faraphel 2024-06-24 22:00:56 +02:00
parent d74605bbb9
commit 53d37d86ab
6 changed files with 171 additions and 96 deletions

View file

@ -1,6 +1,6 @@
# Better WiFi-Direct (BWD)
# Better Wi-Fi Direct (BWD)
This package contain code to improve the base WiFi-Direct implementation.
This package contain code to improve the base Wi-Fi Direct implementation.
The base have some issue, like an abusive usage of listener, error code and events that make using it
very impractical.

View file

@ -18,7 +18,6 @@ import androidx.navigation.compose.rememberNavController
import com.faraphel.tasks_valider.database.TaskDatabase
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun CommunicationInternetSelectScreen(activity: Activity, database: TaskDatabase) {
val controller = rememberNavController()

View file

@ -1,9 +1,7 @@
package com.faraphel.tasks_valider.ui.screen.communication.connection.internet
import android.app.Activity
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
@ -75,7 +73,6 @@ fun CommunicationInternetServerScreen(
}
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun CommunicationInternetServerContent(
database: TaskDatabase,
@ -182,12 +179,7 @@ fun CommunicationInternetServerContent(
val session = database.sessionDao().getById(sessionId)!!
// TODO(Faraphel): remove, this is a test function
Thread {
populateSubjectSessionPersonTest(database, session)
}.let { thread ->
thread.start()
thread.join()
}
populateSubjectSessionPersonTest(database, session)
// Create the server
Log.i("room-server", "creating the server")

View file

@ -6,6 +6,7 @@ import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@ -15,23 +16,20 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.faraphel.tasks_valider.connectivity.bwd.BwdManager
import com.faraphel.tasks_valider.database.TaskDatabase
@Composable
fun CommunicationWifiP2pScreen(activity: Activity) {
fun CommunicationWifiP2pScreen(activity: Activity, database: TaskDatabase) {
val controller = rememberNavController()
var bwdManager: BwdManager? = null
LaunchedEffect(true) {
// start the BWD manager
bwdManager = BwdManager.fromActivity(activity)
}
// create the Wi-Fi Direct manager
val bwdManager = remember { BwdManager.fromActivity(activity) }
NavHost(navController = controller, startDestination = "mode") {
composable("mode") { CommunicationWifiP2pSelectContent(controller) }
// composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) }
composable("server") { CommunicationWifiP2pServerScreen(activity, bwdManager!!) }
composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) }
composable("server") { CommunicationWifiP2pServerScreen(activity, database, bwdManager) }
}
}

View file

@ -1,18 +1,72 @@
package com.faraphel.tasks_valider.ui.screen.communication.connection.wifiP2p
import android.app.Activity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import android.util.Log
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.faraphel.tasks_valider.connectivity.bwd.BwdManager
import com.faraphel.tasks_valider.connectivity.task.TaskClient
import com.faraphel.tasks_valider.connectivity.task.TaskServer
import com.faraphel.tasks_valider.database.TaskDatabase
import com.faraphel.tasks_valider.database.entities.ClassEntity
import com.faraphel.tasks_valider.database.entities.PersonEntity
import com.faraphel.tasks_valider.database.entities.SessionEntity
import com.faraphel.tasks_valider.database.populateSubjectSessionPersonTest
import com.faraphel.tasks_valider.ui.screen.communication.DEFAULT_SERVER_PORT
import com.faraphel.tasks_valider.ui.screen.communication.RANGE_SERVER_PORT
import com.faraphel.tasks_valider.ui.screen.communication.authentication.AuthenticationServerScreen
import com.faraphel.tasks_valider.ui.screen.communication.connection.internet.CommunicationInternetServerContent
import com.faraphel.tasks_valider.ui.screen.task.TaskSessionController
import java.time.Instant
@Composable
fun CommunicationWifiP2pServerScreen(activity: Activity, bwdManager: BwdManager) {
fun CommunicationWifiP2pServerScreen(
activity: Activity,
database: TaskDatabase,
bwdManager: BwdManager
) {
val controller = rememberNavController()
val adminPersonEntityRaw = remember { mutableStateOf<PersonEntity?>(null) }
val adminPersonEntity = remember { mutableStateOf<PersonEntity?>(null) }
val client = remember { mutableStateOf<TaskClient?>(null) }
NavHost(navController = controller, startDestination = "authentication") {
composable("authentication") {
// if the admin person is not created, prompt the user for the admin information
if (adminPersonEntityRaw.value == null) AuthenticationServerScreen(adminPersonEntityRaw)
else controller.navigate("configuration")
}
composable("configuration") {
if (client.value == null)
CommunicationWifiP2pServerContent(
database,
bwdManager,
adminPersonEntityRaw,
adminPersonEntity,
client,
)
else controller.navigate("session")
}
composable("session") {
TaskSessionController(
activity,
client.value!!,
adminPersonEntity.value!!
)
}
}
// TODO(Faraphel): fix and get a user
// if the server is not created, prompt the user for the server configuration
// if (client.value == null) CommunicationWifiP2pServerContent(activity, bwfManager, client)
@ -23,83 +77,115 @@ fun CommunicationWifiP2pServerScreen(activity: Activity, bwdManager: BwdManager)
@Composable
fun CommunicationWifiP2pServerContent(
activity: Activity,
database: TaskDatabase,
bwdManager: BwdManager,
adminPersonEntityRaw: MutableState<PersonEntity?>,
adminPersonEntity: MutableState<PersonEntity?>,
client: MutableState<TaskClient?>
) {
/*
val expandedStudentList = remember { mutableStateOf(false) }
val serverPort = remember { mutableIntStateOf(DEFAULT_SERVER_PORT) }
val classes = remember { mutableStateOf<List<ClassEntity>?>(null) }
val selectedClass = remember { mutableStateOf<ClassEntity?>(null) }
val areClassesExpanded = remember { mutableStateOf(false) }
Column {
// student list
Button(onClick = { expandedStudentList.value = !expandedStudentList.value }) {
Text(text = "Select Students List")
}
DropdownMenu(
expanded = expandedStudentList.value,
onDismissRequest = { expandedStudentList.value = false }
) {
DropdownMenuItem(
text = { Text("ISRI") },
onClick = {}
)
DropdownMenuItem(
text = { Text("MIAGE") },
onClick = {}
)
// TODO(Faraphel): student lists should be loaded from the database or a file
}
LaunchedEffect(true) {
// refresh the list of classes
Thread { refreshClasses(database, classes) }.start()
}
// server port
TextField(
value = serverPort.intValue.toString(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = { text ->
val port = text.toInt()
if (port in RANGE_SERVER_PORT) {
serverPort.intValue = port
}
}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
// title
Text(
text = "New Session",
fontSize = 32.sp
)
Button(onClick = {
// TODO(Faraphel): should be merged with the internet server
// separator
Spacer(modifier = Modifier.height(24.dp))
// Reset the database | TODO(Faraphel): only for testing purpose
activity.deleteDatabase("local")
// Create the database
val database = Room.databaseBuilder(
activity,
TaskDatabase::class.java,
"local"
).build()
// Create the admin
// TODO: the admin should be created from the card reader
val adminPersonEntity = PersonEntity(
"admin",
"admin",
"123456789",
"admin",
)
// Insert the admin in the database
database.personDao().insert(adminPersonEntity)
bwfManager.recreateGroup {
// Create the server
val server = TaskServer(serverPort.intValue, database, adminPersonEntity)
server.start()
// Get the client from the server
client.value = server.getAdminClient()
// classes
Row(verticalAlignment = Alignment.CenterVertically) {
// description
Text(text = "Class", fontSize = 12.sp)
// separator
Spacer(modifier = Modifier.width(width = 12.dp))
// selector
Button(onClick = { areClassesExpanded.value = !areClassesExpanded.value }) {
// display the selected class, if selected
if (selectedClass.value != null) Text(text = selectedClass.value!!.name)
else Text(text = "<Not selected>")
}
// class selector
DropdownMenu(
expanded = areClassesExpanded.value,
onDismissRequest = { areClassesExpanded.value = false }
) {
// TODO(Faraphel): student lists should be loaded from the database or a file
classes.value?.forEach { class_ ->
DropdownMenuItem(
text = { Text(class_.name) },
onClick = {
selectedClass.value = class_
areClassesExpanded.value = false
}
)
}
}
}) {
Text("Create")
}
// check if a class is selected
if (selectedClass.value != null)
// button to create the server
Button(onClick = {
Thread { // a thread is used for networking
// Insert the admin in the database and get its id
val adminPersonEntityId = database.personDao().insert(adminPersonEntityRaw.value!!)
adminPersonEntity.value = database.personDao().getById(adminPersonEntityId)!!
// Create a new session
// TODO(Faraphel): name
val sessionId = database.sessionDao().insert(
SessionEntity(
name="NOM",
start= Instant.now(),
classId=selectedClass.value!!.id,
)
)
val session = database.sessionDao().getById(sessionId)!!
// TODO(Faraphel): remove, this is a test function
populateSubjectSessionPersonTest(database, session)
// create a new Wi-Fi Direct group
bwdManager.recreateGroup {
// Create the server
Log.i("room-server", "creating the server")
val server = TaskServer(
DEFAULT_SERVER_PORT,
database,
session,
adminPersonEntity.value!!,
)
server.start()
// Get the client from the server
client.value = server.getAdminClient()
}
}.start()
}) {
Text("Create")
}
}
*/
}
}
/**
* Refresh the list of classes
*/
fun refreshClasses(database: TaskDatabase, classes: MutableState<List<ClassEntity>?>) {
classes.value = database.classDao().getAll()
}

View file

@ -46,7 +46,7 @@ fun CommunicationModeSelectionScreen(activity: Activity, database: TaskDatabase)
CommunicationInternetSelectScreen(activity, database)
}
composable("wifi-p2p") {
CommunicationWifiP2pScreen(activity)
CommunicationWifiP2pScreen(activity, database)
}
}
}