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 The base have some issue, like an abusive usage of listener, error code and events that make using it
very impractical. very impractical.

View file

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

View file

@ -1,9 +1,7 @@
package com.faraphel.tasks_valider.ui.screen.communication.connection.internet package com.faraphel.tasks_valider.ui.screen.communication.connection.internet
import android.app.Activity import android.app.Activity
import android.os.Build
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button import androidx.compose.material3.Button
@ -75,7 +73,6 @@ fun CommunicationInternetServerScreen(
} }
@RequiresApi(Build.VERSION_CODES.O)
@Composable @Composable
fun CommunicationInternetServerContent( fun CommunicationInternetServerContent(
database: TaskDatabase, database: TaskDatabase,
@ -182,12 +179,7 @@ fun CommunicationInternetServerContent(
val session = database.sessionDao().getById(sessionId)!! val session = database.sessionDao().getById(sessionId)!!
// TODO(Faraphel): remove, this is a test function // TODO(Faraphel): remove, this is a test function
Thread { populateSubjectSessionPersonTest(database, session)
populateSubjectSessionPersonTest(database, session)
}.let { thread ->
thread.start()
thread.join()
}
// Create the server // Create the server
Log.i("room-server", "creating 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.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -15,23 +16,20 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import com.faraphel.tasks_valider.connectivity.bwd.BwdManager import com.faraphel.tasks_valider.connectivity.bwd.BwdManager
import com.faraphel.tasks_valider.database.TaskDatabase
@Composable @Composable
fun CommunicationWifiP2pScreen(activity: Activity) { fun CommunicationWifiP2pScreen(activity: Activity, database: TaskDatabase) {
val controller = rememberNavController() val controller = rememberNavController()
var bwdManager: BwdManager? = null // create the Wi-Fi Direct manager
val bwdManager = remember { BwdManager.fromActivity(activity) }
LaunchedEffect(true) {
// start the BWD manager
bwdManager = BwdManager.fromActivity(activity)
}
NavHost(navController = controller, startDestination = "mode") { NavHost(navController = controller, startDestination = "mode") {
composable("mode") { CommunicationWifiP2pSelectContent(controller) } composable("mode") { CommunicationWifiP2pSelectContent(controller) }
// composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) } composable("client") { CommunicationWifiP2pClientScreen(activity, bwdManager) }
composable("server") { CommunicationWifiP2pServerScreen(activity, bwdManager!!) } composable("server") { CommunicationWifiP2pServerScreen(activity, database, bwdManager) }
} }
} }

View file

@ -1,18 +1,72 @@
package com.faraphel.tasks_valider.ui.screen.communication.connection.wifiP2p package com.faraphel.tasks_valider.ui.screen.communication.connection.wifiP2p
import android.app.Activity import android.app.Activity
import androidx.compose.runtime.Composable import android.util.Log
import androidx.compose.runtime.MutableState import androidx.compose.foundation.layout.*
import androidx.compose.runtime.mutableStateOf import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.remember 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.bwd.BwdManager
import com.faraphel.tasks_valider.connectivity.task.TaskClient 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 @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) } 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 // TODO(Faraphel): fix and get a user
// if the server is not created, prompt the user for the server configuration // if the server is not created, prompt the user for the server configuration
// if (client.value == null) CommunicationWifiP2pServerContent(activity, bwfManager, client) // if (client.value == null) CommunicationWifiP2pServerContent(activity, bwfManager, client)
@ -23,83 +77,115 @@ fun CommunicationWifiP2pServerScreen(activity: Activity, bwdManager: BwdManager)
@Composable @Composable
fun CommunicationWifiP2pServerContent( fun CommunicationWifiP2pServerContent(
activity: Activity, database: TaskDatabase,
bwdManager: BwdManager, bwdManager: BwdManager,
adminPersonEntityRaw: MutableState<PersonEntity?>,
adminPersonEntity: MutableState<PersonEntity?>,
client: MutableState<TaskClient?> client: MutableState<TaskClient?>
) { ) {
/* val classes = remember { mutableStateOf<List<ClassEntity>?>(null) }
val expandedStudentList = remember { mutableStateOf(false) } val selectedClass = remember { mutableStateOf<ClassEntity?>(null) }
val serverPort = remember { mutableIntStateOf(DEFAULT_SERVER_PORT) } val areClassesExpanded = remember { mutableStateOf(false) }
Column { LaunchedEffect(true) {
// student list // refresh the list of classes
Button(onClick = { expandedStudentList.value = !expandedStudentList.value }) { Thread { refreshClasses(database, classes) }.start()
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
}
// server port Column(
TextField( modifier = Modifier.fillMaxSize(),
value = serverPort.intValue.toString(), verticalArrangement = Arrangement.Center,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), horizontalAlignment = Alignment.CenterHorizontally
onValueChange = { text -> ) {
val port = text.toInt() // title
if (port in RANGE_SERVER_PORT) { Text(
serverPort.intValue = port text = "New Session",
} fontSize = 32.sp
}
) )
Button(onClick = { // separator
// TODO(Faraphel): should be merged with the internet server Spacer(modifier = Modifier.height(24.dp))
// Reset the database | TODO(Faraphel): only for testing purpose // classes
activity.deleteDatabase("local") Row(verticalAlignment = Alignment.CenterVertically) {
// description
// Create the database Text(text = "Class", fontSize = 12.sp)
val database = Room.databaseBuilder( // separator
activity, Spacer(modifier = Modifier.width(width = 12.dp))
TaskDatabase::class.java, // selector
"local" Button(onClick = { areClassesExpanded.value = !areClassesExpanded.value }) {
).build() // display the selected class, if selected
if (selectedClass.value != null) Text(text = selectedClass.value!!.name)
// Create the admin else Text(text = "<Not selected>")
// TODO: the admin should be created from the card reader }
val adminPersonEntity = PersonEntity(
"admin", // class selector
"admin", DropdownMenu(
"123456789", expanded = areClassesExpanded.value,
"admin", onDismissRequest = { areClassesExpanded.value = false }
) {
) // TODO(Faraphel): student lists should be loaded from the database or a file
classes.value?.forEach { class_ ->
// Insert the admin in the database DropdownMenuItem(
database.personDao().insert(adminPersonEntity) text = { Text(class_.name) },
onClick = {
bwfManager.recreateGroup { selectedClass.value = class_
// Create the server areClassesExpanded.value = false
val server = TaskServer(serverPort.intValue, database, adminPersonEntity) }
server.start() )
}
// Get the client from the server
client.value = server.getAdminClient()
} }
}) {
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) CommunicationInternetSelectScreen(activity, database)
} }
composable("wifi-p2p") { composable("wifi-p2p") {
CommunicationWifiP2pScreen(activity) CommunicationWifiP2pScreen(activity, database)
} }
} }
} }