mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-05 10:52:13 +00:00
Connect Huawei push notifications
This commit is contained in:
@@ -1,60 +1,22 @@
|
||||
package org.thoughtcrime.securesms.notifications
|
||||
|
||||
import android.content.Context
|
||||
import com.goterl.lazysodium.LazySodiumAndroid
|
||||
import com.goterl.lazysodium.SodiumAndroid
|
||||
import com.goterl.lazysodium.interfaces.AEAD
|
||||
import com.goterl.lazysodium.interfaces.Sign
|
||||
import com.goterl.lazysodium.utils.Key
|
||||
import com.goterl.lazysodium.utils.KeyPair
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import nl.komponents.kovenant.Promise
|
||||
import nl.komponents.kovenant.combine.and
|
||||
import nl.komponents.kovenant.functional.map
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationMetadata
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.Response
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionRequest
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionResponse
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscribeResponse
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscriptionRequest
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||
import org.session.libsession.snode.OnionRequestAPI
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.snode.Version
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.getLocalNumber
|
||||
import org.session.libsession.utilities.bencode.Bencode
|
||||
import org.session.libsession.utilities.bencode.BencodeList
|
||||
import org.session.libsession.utilities.bencode.BencodeString
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsession.utilities.Device
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.emptyPromise
|
||||
import org.session.libsignal.utilities.retryIfNeeded
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
import org.thoughtcrime.securesms.crypto.KeyPairUtilities
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val TAG = "FirebasePushManager"
|
||||
|
||||
class FirebasePushManager(
|
||||
private val context: Context
|
||||
): PushManager {
|
||||
@Singleton
|
||||
class FirebasePushManager @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
): PushManager {
|
||||
|
||||
@Inject lateinit var pushManagerV2: PushManagerV2
|
||||
@Inject lateinit var genericPushManager: GenericPushManager
|
||||
|
||||
companion object {
|
||||
const val maxRetryCount = 4
|
||||
}
|
||||
|
||||
private val tokenManager = FcmTokenManager(context, ExpiryManager(context))
|
||||
private var firebaseInstanceIdJob: Job? = null
|
||||
|
||||
@Synchronized
|
||||
@@ -67,70 +29,9 @@ class FirebasePushManager(
|
||||
|
||||
firebaseInstanceIdJob = getFcmInstanceId { task ->
|
||||
when {
|
||||
task.isSuccessful -> try { task.result?.token?.let { refresh(it, force).get() } } catch(e: Exception) { Log.e(TAG, "refresh() failed", e) }
|
||||
task.isSuccessful -> try { task.result?.token?.let { genericPushManager.refresh(it, force).get() } } catch(e: Exception) { Log.e(TAG, "refresh() failed", e) }
|
||||
else -> Log.w(TAG, "getFcmInstanceId failed." + task.exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refresh(token: String, force: Boolean): Promise<*, Exception> {
|
||||
Log.d(TAG, "refresh() called")
|
||||
|
||||
val userPublicKey = getLocalNumber(context) ?: return emptyPromise()
|
||||
val userEdKey = KeyPairUtilities.getUserED25519KeyPair(context) ?: return emptyPromise()
|
||||
|
||||
return when {
|
||||
tokenManager.isUsingFCM -> register(force, token, userPublicKey, userEdKey)
|
||||
tokenManager.requiresUnregister -> unregister(token, userPublicKey, userEdKey)
|
||||
else -> emptyPromise()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register for push notifications if:
|
||||
* force is true
|
||||
* there is no FCM Token
|
||||
* FCM Token has expired
|
||||
*/
|
||||
private fun register(
|
||||
force: Boolean,
|
||||
token: String,
|
||||
publicKey: String,
|
||||
userEd25519Key: KeyPair,
|
||||
namespaces: List<Int> = listOf(Namespace.DEFAULT)
|
||||
): Promise<*, Exception> = if (force || tokenManager.isInvalid()) {
|
||||
register(token, publicKey, userEd25519Key, namespaces)
|
||||
} else emptyPromise()
|
||||
|
||||
/**
|
||||
* Register for push notifications.
|
||||
*/
|
||||
private fun register(
|
||||
token: String,
|
||||
publicKey: String,
|
||||
userEd25519Key: KeyPair,
|
||||
namespaces: List<Int> = listOf(Namespace.DEFAULT)
|
||||
): Promise<*, Exception> = PushManagerV1.register(
|
||||
token = token,
|
||||
publicKey = publicKey
|
||||
) and pushManagerV2.register(
|
||||
token, publicKey, userEd25519Key, namespaces
|
||||
) fail {
|
||||
Log.e(TAG, "registerBoth failed", it)
|
||||
} success {
|
||||
Log.d(TAG, "registerBoth success... saving token!!")
|
||||
tokenManager.fcmToken = token
|
||||
}
|
||||
|
||||
private fun unregister(
|
||||
token: String,
|
||||
userPublicKey: String,
|
||||
userEdKey: KeyPair
|
||||
): Promise<*, Exception> = PushManagerV1.unregister() and pushManagerV2.unregister(
|
||||
token, userPublicKey, userEdKey
|
||||
) fail {
|
||||
Log.e(TAG, "unregisterBoth failed", it)
|
||||
} success {
|
||||
tokenManager.fcmToken = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,13 @@
|
||||
package org.thoughtcrime.securesms.notifications
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object FirebasePushModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFirebasePushManager(
|
||||
@ApplicationContext context: Context,
|
||||
) = FirebasePushManager(context)
|
||||
}
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class FirebaseBindingModule {
|
||||
@Binds
|
||||
abstract fun bindPushManager(firebasePushManager: FirebasePushManager): PushManager
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.thoughtcrime.securesms.notifications
|
||||
|
||||
import android.content.Context
|
||||
import com.goterl.lazysodium.utils.KeyPair
|
||||
import nl.komponents.kovenant.Promise
|
||||
import nl.komponents.kovenant.combine.and
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
|
||||
import org.session.libsession.utilities.Device
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.emptyPromise
|
||||
import org.thoughtcrime.securesms.crypto.KeyPairUtilities
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val TAG = "GenericPushManager"
|
||||
|
||||
@Singleton
|
||||
class GenericPushManager @Inject constructor(
|
||||
private val context: Context,
|
||||
private val device: Device,
|
||||
private val tokenManager: FcmTokenManager,
|
||||
private val pushManagerV2: PushManagerV2,
|
||||
) {
|
||||
fun refresh(token: String, force: Boolean): Promise<*, Exception> {
|
||||
Log.d(TAG, "refresh() called")
|
||||
|
||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return emptyPromise()
|
||||
val userEdKey = KeyPairUtilities.getUserED25519KeyPair(context) ?: return emptyPromise()
|
||||
|
||||
return when {
|
||||
tokenManager.isUsingFCM -> register(force, token, userPublicKey, userEdKey)
|
||||
tokenManager.requiresUnregister -> unregister(token, userPublicKey, userEdKey)
|
||||
else -> emptyPromise()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register for push notifications if:
|
||||
* force is true
|
||||
* there is no FCM Token
|
||||
* FCM Token has expired
|
||||
*/
|
||||
private fun register(
|
||||
force: Boolean,
|
||||
token: String,
|
||||
publicKey: String,
|
||||
userEd25519Key: KeyPair,
|
||||
namespaces: List<Int> = listOf(Namespace.DEFAULT)
|
||||
): Promise<*, Exception> = if (force || tokenManager.isInvalid()) {
|
||||
register(token, publicKey, userEd25519Key, namespaces)
|
||||
} else emptyPromise()
|
||||
|
||||
/**
|
||||
* Register for push notifications.
|
||||
*/
|
||||
private fun register(
|
||||
token: String,
|
||||
publicKey: String,
|
||||
userEd25519Key: KeyPair,
|
||||
namespaces: List<Int> = listOf(Namespace.DEFAULT)
|
||||
): Promise<*, Exception> = PushManagerV1.register(
|
||||
token = token,
|
||||
device = device,
|
||||
publicKey = publicKey
|
||||
) and pushManagerV2.register(
|
||||
token, publicKey, userEd25519Key, namespaces
|
||||
) fail {
|
||||
Log.e(TAG, "registerBoth failed", it)
|
||||
} success {
|
||||
Log.d(TAG, "registerBoth success... saving token!!")
|
||||
tokenManager.fcmToken = token
|
||||
}
|
||||
|
||||
private fun unregister(
|
||||
token: String,
|
||||
userPublicKey: String,
|
||||
userEdKey: KeyPair
|
||||
): Promise<*, Exception> = PushManagerV1.unregister() and pushManagerV2.unregister(
|
||||
token, userPublicKey, userEdKey
|
||||
) fail {
|
||||
Log.e(TAG, "unregisterBoth failed", it)
|
||||
} success {
|
||||
tokenManager.fcmToken = null
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
package org.thoughtcrime.securesms.notifications
|
||||
|
||||
import android.content.Context
|
||||
import com.goterl.lazysodium.LazySodiumAndroid
|
||||
import com.goterl.lazysodium.SodiumAndroid
|
||||
import com.goterl.lazysodium.interfaces.AEAD
|
||||
import com.goterl.lazysodium.interfaces.Sign
|
||||
import com.goterl.lazysodium.utils.Key
|
||||
import com.goterl.lazysodium.utils.KeyPair
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
@@ -16,30 +12,22 @@ import nl.komponents.kovenant.functional.map
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationMetadata
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.Response
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.Server
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionRequest
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionResponse
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscribeResponse
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscriptionRequest
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.*
|
||||
import org.session.libsession.snode.OnionRequestAPI
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.snode.Version
|
||||
import org.session.libsession.utilities.bencode.Bencode
|
||||
import org.session.libsession.utilities.bencode.BencodeList
|
||||
import org.session.libsession.utilities.bencode.BencodeString
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.retryIfNeeded
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val TAG = "PushManagerV2"
|
||||
private const val maxRetryCount = 4
|
||||
|
||||
class PushManagerV2(private val pushHandler: PushHandler) {
|
||||
@Singleton
|
||||
class PushManagerV2 @Inject constructor(private val pushHandler: PushHandler) {
|
||||
private val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
|
||||
fun register(
|
||||
@@ -98,7 +86,7 @@ class PushManagerV2(private val pushHandler: PushHandler) {
|
||||
}
|
||||
|
||||
private inline fun <reified T: Response> retryResponseBody(path: String, requestParameters: String): Promise<T, Exception> =
|
||||
retryIfNeeded(FirebasePushManager.maxRetryCount) { getResponseBody(path, requestParameters) }
|
||||
retryIfNeeded(maxRetryCount) { getResponseBody(path, requestParameters) }
|
||||
|
||||
private inline fun <reified T: Response> getResponseBody(path: String, requestParameters: String): Promise<T, Exception> {
|
||||
val server = Server.LATEST
|
||||
|
||||
@@ -19,7 +19,7 @@ private const val TAG = "PushNotificationService"
|
||||
@AndroidEntryPoint
|
||||
class PushNotificationService : FirebaseMessagingService() {
|
||||
|
||||
@Inject lateinit var pushManager: FirebasePushManager
|
||||
@Inject lateinit var pushManager: PushManager
|
||||
@Inject lateinit var pushHandler: PushHandler
|
||||
|
||||
override fun onNewToken(token: String) {
|
||||
|
||||
Reference in New Issue
Block a user