This commit is contained in:
gouri-panda 2020-11-04 17:09:34 +05:30
parent fca94d2ee1
commit a2ee2fa345
2 changed files with 75 additions and 97 deletions

View File

@ -17,10 +17,11 @@
*/ */
package org.kiwix.kiwixmobile.localFileTransfer package org.kiwix.kiwixmobile.localFileTransfer
import android.os.AsyncTask
import android.util.Log import android.util.Log
import android.widget.Toast import kotlinx.coroutines.Dispatchers
import org.kiwix.kiwixmobile.R import kotlinx.coroutines.async
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
import org.kiwix.kiwixmobile.core.BuildConfig import org.kiwix.kiwixmobile.core.BuildConfig
import java.io.InputStream import java.io.InputStream
import java.io.ObjectInputStream import java.io.ObjectInputStream
@ -45,75 +46,68 @@ import java.util.ArrayList
* initiates the file transfer through [SenderDevice] on the sender and using * initiates the file transfer through [SenderDevice] on the sender and using
* [ReceiverDevice] on the receiver. * [ReceiverDevice] on the receiver.
*/ */
internal class PeerGroupHandshakeAsyncTask(private val wifiDirectManager: WifiDirectManager) : internal class PeerGroupHandshakeAsyncTask(private val wifiDirectManager: WifiDirectManager) {
AsyncTask<Void?, Void?, InetAddress?>() {
private val HANDSHAKE_MESSAGE = "Request Kiwix File Sharing" private val HANDSHAKE_MESSAGE = "Request Kiwix File Sharing"
override fun doInBackground(vararg voids: Void?): InetAddress? { suspend fun peer(): InetAddress? = withContext(Dispatchers.IO) {
if (BuildConfig.DEBUG) { val job = async {
Log.d(TAG, "Handshake in progress") if (BuildConfig.DEBUG) {
} Log.d(TAG, "Handshake in progress")
if (wifiDirectManager.isGroupFormed && wifiDirectManager.isGroupOwner && !isCancelled) { }
try { if (wifiDirectManager.isGroupFormed && wifiDirectManager.isGroupOwner && this.isActive) {
ServerSocket(PEER_HANDSHAKE_PORT) try {
.use { serverSocket -> ServerSocket(PEER_HANDSHAKE_PORT)
serverSocket.reuseAddress = true .use { serverSocket ->
val server = serverSocket.accept() serverSocket.reuseAddress = true
val objectInputStream = val server = serverSocket.accept()
ObjectInputStream(server.getInputStream()) val objectInputStream = ObjectInputStream(server.getInputStream())
val `object` = objectInputStream.readObject() val kiwixHandShakeMessage = objectInputStream.readObject()
// Verify that the peer trying to communicate is a kiwix app intending to transfer files // Verify that the peer trying to communicate is a kiwix app intending to transfer files
return@doInBackground if (isKiwixHandshake(`object`) && !isCancelled) { return@async if (isKiwixHandshake(kiwixHandShakeMessage) && this.isActive) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Log.d( Log.d(TAG, "Client IP address: " + server.inetAddress)
TAG, }
"Client IP address: " + server.inetAddress exchangeFileTransferMetadata(server.getOutputStream(), server.getInputStream())
) server.inetAddress
} else {
// Selected device is not accepting wifi direct connections through the kiwix app
null
} }
exchangeFileTransferMetadata(server.getOutputStream(), server.getInputStream())
server.inetAddress
} else { // Selected device is not accepting wifi direct connections through the kiwix app
null
} }
} } catch (ex: Exception) {
} catch (ex: Exception) { ex.printStackTrace()
ex.printStackTrace() return@async null
return null }
} } else if (wifiDirectManager.isGroupFormed && this.isActive) { // && !groupInfo.isGroupOwner
} else if (wifiDirectManager.isGroupFormed && !isCancelled) { //&& !groupInfo.isGroupOwner try {
try { Socket().use { client ->
Socket().use { client -> client.reuseAddress = true
client.reuseAddress = true client.connect(
client.connect( InetSocketAddress(
InetSocketAddress( wifiDirectManager.groupOwnerAddress.hostAddress,
wifiDirectManager.groupOwnerAddress.hostAddress, PEER_HANDSHAKE_PORT
PEER_HANDSHAKE_PORT ), 15000
), 15000 )
) val objectOutputStream = ObjectOutputStream(client.getOutputStream())
val objectOutputStream = // Send message for the peer device to verify
ObjectOutputStream(client.getOutputStream()) objectOutputStream.writeObject(HANDSHAKE_MESSAGE)
objectOutputStream.writeObject( exchangeFileTransferMetadata(client.getOutputStream(), client.getInputStream())
HANDSHAKE_MESSAGE return@async wifiDirectManager.groupOwnerAddress
) // Send message for the peer device to verify }
exchangeFileTransferMetadata(client.getOutputStream(), client.getInputStream()) } catch (ex: Exception) {
return@doInBackground wifiDirectManager.groupOwnerAddress ex.printStackTrace()
return@async null
} }
} catch (ex: Exception) {
ex.printStackTrace()
return null
} }
return@async null
} }
return null return@withContext job.await()
} }
private fun isKiwixHandshake(`object`: Any): Boolean { private fun isKiwixHandshake(handshakeMessage: Any): Boolean =
return HANDSHAKE_MESSAGE == `object` HANDSHAKE_MESSAGE == handshakeMessage
}
private fun exchangeFileTransferMetadata( private fun exchangeFileTransferMetadata(outputStream: OutputStream, inputStream: InputStream) {
outputStream: OutputStream,
inputStream: InputStream
) {
if (wifiDirectManager.isFileSender) { if (wifiDirectManager.isFileSender) {
try { try {
ObjectOutputStream(outputStream).use { objectOutputStream -> ObjectOutputStream(outputStream).use { objectOutputStream ->
@ -123,10 +117,7 @@ internal class PeerGroupHandshakeAsyncTask(private val wifiDirectManager: WifiDi
wifiDirectManager.getFilesForTransfer() wifiDirectManager.getFilesForTransfer()
for (fileItem in fileItemArrayList) { // Send the names of each of those files, in order for (fileItem in fileItemArrayList) { // Send the names of each of those files, in order
objectOutputStream.writeObject(fileItem.fileName) objectOutputStream.writeObject(fileItem.fileName)
Log.d( Log.d(TAG, "Sending " + fileItem.fileUri.toString())
TAG,
"Sending " + fileItem.fileUri.toString()
)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -136,22 +127,16 @@ internal class PeerGroupHandshakeAsyncTask(private val wifiDirectManager: WifiDi
try { try {
ObjectInputStream(inputStream).use { objectInputStream -> ObjectInputStream(inputStream).use { objectInputStream ->
// Read the number of files // Read the number of files
val totalFilesObject = Integer.parseInt(objectInputStream.readObject().toString()) val totalFilesObject = objectInputStream.readObject().toString()
if (totalFilesObject.javaClass == String::class.java) { if (totalFilesObject.javaClass == String::class.java) {
val total: Int = totalFilesObject val total: Int = totalFilesObject.toInt()
if (BuildConfig.DEBUG) Log.d( if (BuildConfig.DEBUG) Log.d(TAG, "Metadata: $total files")
TAG,
"Metadata: $total files"
)
val fileItems = ArrayList<FileItem>() val fileItems = ArrayList<FileItem>()
for (i in 0 until total) { // Read names of each of those files, in order for (i in 0 until total) { // Read names of each of those files, in order
val fileNameObject = objectInputStream.readObject() val fileNameObject = objectInputStream.readObject()
if (fileNameObject.javaClass == String::class.java) { if (fileNameObject.javaClass == String::class.java) {
fileItems.add(FileItem((fileNameObject as String))) fileItems.add(FileItem((fileNameObject as String)))
if (BuildConfig.DEBUG) Log.d( if (BuildConfig.DEBUG) Log.d(TAG, "Expecting $fileNameObject")
TAG,
"Expecting $fileNameObject"
)
} }
} }
wifiDirectManager.setFilesForTransfer(fileItems) wifiDirectManager.setFilesForTransfer(fileItems)
@ -163,25 +148,6 @@ internal class PeerGroupHandshakeAsyncTask(private val wifiDirectManager: WifiDi
} }
} }
override fun onCancelled() {
Log.d(
TAG,
"PeerGroupHandshakeAsyncTask cancelled"
)
}
override fun onPostExecute(inetAddress: InetAddress?) {
if (inetAddress != null) {
wifiDirectManager.setClientAddress(inetAddress)
} else {
if (BuildConfig.DEBUG) {
Log.d(TAG, "InetAddress is null")
}
wifiDirectManager.displayToast(R.string.connection_refused, "", Toast.LENGTH_LONG)
wifiDirectManager.onFileTransferAsyncTaskComplete(false)
}
}
companion object { companion object {
private const val TAG = "PeerGrpHndshakeAsyncTsk" private const val TAG = "PeerGrpHndshakeAsyncTsk"
private const val PEER_HANDSHAKE_PORT = 8009 private const val PEER_HANDSHAKE_PORT = 8009

View File

@ -248,7 +248,19 @@ class WifiDirectManager @Inject constructor(
Log.d(TAG, "Starting handshake") Log.d(TAG, "Starting handshake")
} }
peerGroupHandshakeAsyncTask = PeerGroupHandshakeAsyncTask(this) peerGroupHandshakeAsyncTask = PeerGroupHandshakeAsyncTask(this)
.also { it.execute() } .also {
CoroutineScope(Dispatchers.Main).launch {
val inetAddress = it.peer()
inetAddress?.let(::setClientAddress) ?: if (BuildConfig.DEBUG) {
Log.d(TAG, "InetAddress is null")
withContext(Dispatchers.Main) {
displayToast(R.string.connection_refused, "", Toast.LENGTH_LONG)
onFileTransferAsyncTaskComplete(false)
}
}
}
}
} }
val totalFilesForTransfer: Int val totalFilesForTransfer: Int
@ -319,7 +331,7 @@ class WifiDirectManager @Inject constructor(
} }
fun stopWifiDirectManager() { fun stopWifiDirectManager() {
cancelAsyncTasks(peerGroupHandshakeAsyncTask) cancelAsyncTasks()
if (isFileSender) { if (isFileSender) {
closeChannel() closeChannel()
} else { } else {