Use failed reasons

This commit is contained in:
sim 2024-10-28 16:26:29 +00:00
parent 5b5ce7575e
commit c851d69baa
4 changed files with 124 additions and 49 deletions

View File

@ -29,7 +29,6 @@ object Distributor {
broadcastIntent.`package` = application
broadcastIntent.action = ACTION_MESSAGE
broadcastIntent.putExtra(EXTRA_TOKEN, connectorToken)
broadcastIntent.putExtra(EXTRA_MESSAGE, String(message))
broadcastIntent.putExtra(EXTRA_BYTES_MESSAGE, message)
context.sendBroadcast(broadcastIntent)
Log.d(TAG, "Message forwarded")
@ -53,7 +52,7 @@ object Distributor {
context: Context,
application: String,
connectorToken: String,
message: String = ""
reason: FailedReason
) {
application.ifBlank {
return
@ -62,7 +61,7 @@ object Distributor {
broadcastIntent.`package` = application
broadcastIntent.action = ACTION_REGISTRATION_FAILED
broadcastIntent.putExtra(EXTRA_TOKEN, connectorToken)
broadcastIntent.putExtra(EXTRA_MESSAGE, message)
broadcastIntent.putExtra(EXTRA_FAILED_REASON, reason.name)
context.sendBroadcast(broadcastIntent)
}
@ -115,12 +114,17 @@ object Distributor {
Api(context).apiDeleteDevice(block)
}
fun createApp(context: Context, appName: String, connectorToken: String, block: () -> Unit) {
/**
* Create an application on the server, runs [block] when it's done.
*
* [block]'s parameter is `true` if we have successfully created the registration.
*/
fun createApp(context: Context, appName: String, connectorToken: String, block: (Boolean) -> Unit) {
Api(context).apiCreateApp(appName) { nextpushToken ->
nextpushToken?.let {
getDb(context).registerApp(appName, connectorToken, it)
}
block()
block(true)
} ?: block(false)
}
}

View File

@ -0,0 +1,23 @@
package org.unifiedpush.distributor.nextpush.distributor
/**
* A registration request may fail for different reasons.
*/
enum class FailedReason {
/**
* This is a generic error type, you can try to register again directly.
*/
INTERNAL_ERROR,
/**
* The registration failed because of missing network connection, try again when network is back.
*/
NETWORK,
/**
* The distributor requires a user action to work. For instance, the distributor may be log out of the push server and requires the user to log in. The user must interact with the distributor or sending a new registration will fail again.
*/
ACTION_REQUIRED,
/*
* The distributor requires a VAPID key and the app didn't provide one during registration.
VAPID_REQUIRED,
*/
}

View File

@ -17,5 +17,5 @@ const val EXTRA_APPLICATION = "application"
const val EXTRA_PI = "pi"
const val EXTRA_TOKEN = "token"
const val EXTRA_ENDPOINT = "endpoint"
const val EXTRA_MESSAGE = "message"
const val EXTRA_FAILED_REASON = "reason"
const val EXTRA_BYTES_MESSAGE = "bytesMessage"

View File

@ -132,54 +132,102 @@ class RegisterBroadcastReceiver : BroadcastReceiver() {
private fun onRegister(context: Context, connectorToken: String, application: String) {
if (!AppCompanion.createQueue.containsTokenElseAdd(connectorToken)) {
when (checkToken(context, connectorToken, application)) {
ConnectorTokenValidity.TOKEN_REGISTERED_OK -> {
sendEndpoint(context, connectorToken)
AppCompanion.createQueue.removeToken(connectorToken)
}
ConnectorTokenValidity.TOKEN_NOK -> {
sendRegistrationFailed(
context,
application,
connectorToken
)
AppCompanion.createQueue.removeToken(connectorToken)
}
ConnectorTokenValidity.TOKEN_NEW -> {
val appName = context.getApplicationName(application) ?: application
if (!isConnected(context)) {
sendRegistrationFailed(
context,
application,
connectorToken,
message = "NextPush is not connected"
)
Toast.makeText(
context,
"Cannot register $appName, NextPush is not connected.",
Toast.LENGTH_SHORT
).show()
return
}
createApp(
context,
application,
connectorToken
) {
sendEndpoint(context, connectorToken)
AppCompanion.createQueue.removeToken(connectorToken)
Toast.makeText(
context,
"$appName registered.",
Toast.LENGTH_SHORT
).show()
}
}
ConnectorTokenValidity.TOKEN_REGISTERED_OK -> onRegisterKnownToken(context, connectorToken)
ConnectorTokenValidity.TOKEN_NOK -> onRegisterNokToken(context, connectorToken, application)
ConnectorTokenValidity.TOKEN_NEW ->onRegisterNewToken(context, connectorToken, application)
}
AppCompanion.createQueue.removeToken(connectorToken)
} else {
Log.d(TAG, "Already registering this token")
}
}
/**
* The token is known, send the endpoint.
*/
private fun onRegisterKnownToken(context: Context, connectorToken: String) {
sendEndpoint(context, connectorToken)
}
/**
* The token exists but don't match the application, we send a registration fail with INTERNAL_ERROR
* so the application can start again with a new token.
*/
private fun onRegisterNokToken(context: Context, connectorToken: String, application: String) {
sendRegistrationFailed(
context,
application,
connectorToken,
FailedReason.INTERNAL_ERROR
)
}
/**
* Registering a new token.
*
* If we are not connected to Nextcloud, we send registration failed with [FailedReason.ACTION_REQUIRED]
*/
private fun onRegisterNewToken(context: Context, connectorToken: String, application: String) {
val appName = context.getApplicationName(application) ?: application
when {
!isConnected(context) -> registrationFailedWithToast(
context,
connectorToken,
application,
FailedReason.ACTION_REQUIRED
)
!AppCompanion.hasInternet.get() -> registrationFailedWithToast(
context,
connectorToken,
application,
FailedReason.NETWORK
)
else -> createApp(
context,
application,
connectorToken
) { success ->
when (success) {
true -> {
sendEndpoint(context, connectorToken)
Toast.makeText(context, "$appName registered.", Toast.LENGTH_SHORT)
.show()
}
false -> registrationFailedWithToast(
context,
connectorToken,
application,
FailedReason.INTERNAL_ERROR
)
}
}
}
}
/** Send registration failed and toast */
private fun registrationFailedWithToast(context: Context, connectorToken: String, application: String, failedReason: FailedReason) {
val appName = context.getApplicationName(application) ?: application
sendRegistrationFailed(
context,
application,
connectorToken,
failedReason
)
val text = when (failedReason) {
FailedReason.NETWORK -> "Cannot register $appName, no internet."
FailedReason.ACTION_REQUIRED -> "Cannot register $appName, logged out."
FailedReason.INTERNAL_ERROR -> "Cannot register $appName, internal error."
}
Toast.makeText(
context,
text,
Toast.LENGTH_SHORT
).show()
}
/**
* Unregister the application from the server and remove from the local db
*/