[Android, iOS]: Initialization check, no disconnect on closing (#9)

* feat(android, dart): add check for initialization, show proper error messages

* feat(exception): add exception mapper for android and ios

* feat(ios): check initialization in swift

* fix(android): add initialization check for methods, remove disconnect() inside onDetachedFromEngine

* chore: code style, version, changelog
This commit is contained in:
Kseniia Nikitina
2024-08-09 21:22:58 +02:00
committed by GitHub
parent 906e87c6a9
commit a5c77f58e5
22 changed files with 306 additions and 102 deletions
@@ -0,0 +1,12 @@
package com.xenikii.nearby_service
class ErrorCodes {
companion object {
const val P2P_UNSUPPORTED = "P2P_UNSUPPORTED"
const val ERROR = "ERROR"
const val BUSY = "BUSY"
const val NO_SERVICE_REQUESTS = "NO_SERVICE_REQUESTS"
const val UNKNOWN = "UNKNOWN"
const val NO_INITIALIZATION = "NO_INITIALIZATION"
}
}
@@ -87,6 +87,8 @@ class NearbyServiceManager(private var context: Context) {
* It also may be null.
*/
fun getCurrentDevice(result: Result) {
if (!checkInitialization(result)) return
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
wifiManager.requestDeviceInfo(wifiChannel) { device ->
@@ -119,6 +121,8 @@ class NearbyServiceManager(private var context: Context) {
* All permissions from [NearbyServicePermissionsHandler] are required.
*/
fun discover(result: Result) {
if (!checkInitialization(result)) return
try {
wifiManager.discoverPeers(
wifiChannel, getActionListener(
@@ -139,6 +143,8 @@ class NearbyServiceManager(private var context: Context) {
* Stop discovery for peers in Wi-fi Direct scope.
*/
fun stopDiscovery(result: Result) {
if (!checkInitialization(result)) return
wifiManager.stopPeerDiscovery(
wifiChannel, getActionListener(
result,
@@ -152,6 +158,8 @@ class NearbyServiceManager(private var context: Context) {
* Returns peers from [NearbyServiceBroadcastReceiver].
*/
fun getPeers(result: Result) {
if (!checkInitialization(result)) return
result.success(receiver.peers)
}
@@ -159,6 +167,8 @@ class NearbyServiceManager(private var context: Context) {
* Returns connection info from [NearbyServiceBroadcastReceiver] in json string.
*/
fun getConnectionInfo(result: Result) {
if (!checkInitialization(result)) return
val info = receiver.wifiInfo?.toJsonString()
result.success(info)
}
@@ -167,6 +177,8 @@ class NearbyServiceManager(private var context: Context) {
* Connects to provided [deviceAddress] in Wi-fi Direct scope.
*/
fun connect(result: Result, deviceAddress: String) {
if (!checkInitialization(result)) return
val config = WifiP2pConfig()
if (receiver.connectedDevice?.deviceAddress == deviceAddress) {
Logger.i("Already connected to the device $deviceAddress")
@@ -196,6 +208,8 @@ class NearbyServiceManager(private var context: Context) {
* Disconnect from a previous device in Wi-fi Direct scope.
*/
fun disconnect(result: Result? = null) {
if (!checkInitialization(result)) return
val actionListener = getActionListener(
result, "Disconnected from last device", "Failed to disconnect"
)
@@ -204,6 +218,8 @@ class NearbyServiceManager(private var context: Context) {
}
fun cancelConnect(result: Result? = null) {
if (!checkInitialization(result)) return
val actionListener = getActionListener(
result,
"Last connection request was cancelled",
@@ -240,6 +256,31 @@ class NearbyServiceManager(private var context: Context) {
}
}
private fun checkInitialization(result: Result?, shouldLog: Boolean = true): Boolean {
try {
if (!::wifiManager.isInitialized) {
Logger.e("WifiManager is not initialized. Please call 'initialize()' first")
result?.success(ErrorCodes.NO_INITIALIZATION)
return false
}
if (!::wifiChannel.isInitialized) {
Logger.e("WifiChannel is not initialized. Please call 'initialize()' first")
result?.success(ErrorCodes.NO_INITIALIZATION)
return false
}
if (!::receiver.isInitialized) {
Logger.e("Broadcast Receiver is not initialized. Please call 'initialize()' first")
result?.success(ErrorCodes.NO_INITIALIZATION)
return false
}
} catch (e: Exception) {
Logger.e("Failed to check initialization, please call 'initialize()' first")
result?.success(ErrorCodes.NO_INITIALIZATION)
return false
}
return true
}
private fun getActionListener(
result: Result?,
successMessage: String? = null,
@@ -262,11 +303,11 @@ class NearbyServiceManager(private var context: Context) {
else -> "An unknown error occurred. Please check the device's Wi-Fi P2P settings and ensure the device supports Wi-Fi P2P."
}
val stringifyReasonCode = when (reasonCode) {
WifiP2pManager.P2P_UNSUPPORTED -> "P2P_UNSUPPORTED"
WifiP2pManager.ERROR -> "ERROR"
WifiP2pManager.BUSY -> "BUSY"
WifiP2pManager.NO_SERVICE_REQUESTS -> "NO_SERVICE_REQUESTS"
else -> "UNKNOWN"
WifiP2pManager.P2P_UNSUPPORTED -> ErrorCodes.P2P_UNSUPPORTED
WifiP2pManager.ERROR -> ErrorCodes.ERROR
WifiP2pManager.BUSY -> ErrorCodes.BUSY
WifiP2pManager.NO_SERVICE_REQUESTS -> ErrorCodes.NO_SERVICE_REQUESTS
else -> ErrorCodes.UNKNOWN
}
Logger.e("$errorMessage, Reason code: $reasonCode, Reason: $reason")
result?.success(stringifyReasonCode)
@@ -281,6 +322,8 @@ class NearbyServiceManager(private var context: Context) {
val postCallback = object : Runnable {
override fun run() {
if (!checkInitialization(null, false)) return
handler.post { eventSink?.success("${receiver.peers}") }
handler.postDelayed(this, 1000)
}
@@ -306,6 +349,8 @@ class NearbyServiceManager(private var context: Context) {
val postCallback = object : Runnable {
override fun run() {
if (!checkInitialization(null, false)) return
handler.post { eventSink?.success(receiver.connectedDevice?.toJsonString()) }
handler.postDelayed(this, 1000)
}
@@ -330,6 +375,8 @@ class NearbyServiceManager(private var context: Context) {
val postCallback = object : Runnable {
override fun run() {
if (!checkInitialization(null, false)) return
handler.post { eventSink?.success(receiver.wifiInfo?.toJsonString()) }
handler.postDelayed(this, 1000)
}
@@ -177,7 +177,6 @@ class NearbyServicePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
channel.setMethodCallHandler(null)
peersChannel.setStreamHandler(null)
connectedDeviceChannel.setStreamHandler(null)
manager.disconnect()
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {