Connect Huawei push notifications

This commit is contained in:
Andrew 2023-07-26 10:48:20 +09:30
parent 34990b13d3
commit 55216875ac
20 changed files with 231 additions and 215 deletions

View File

@ -133,7 +133,7 @@ android {
apply plugin: 'com.google.gms.google-services'
ext.websiteUpdateUrl = "null"
buildConfigField "boolean", "PLAY_STORE_DISABLED", "false"
buildConfigField "String", "DEVICE", "\"android\""
buildConfigField "org.session.libsession.utilities.Device", "DEVICE", "org.session.libsession.utilities.Device.ANDROID"
buildConfigField "String", "NOPLAY_UPDATE_URL", "$ext.websiteUpdateUrl"
}
@ -141,7 +141,7 @@ android {
dimension "distribution"
ext.websiteUpdateUrl = "null"
buildConfigField "boolean", "PLAY_STORE_DISABLED", "true"
buildConfigField "String", "DEVICE", "\"huawei\""
buildConfigField "org.session.libsession.utilities.Device", "DEVICE", "org.session.libsession.utilities.Device.HUAWEI"
buildConfigField "String", "NOPLAY_UPDATE_URL", "$ext.websiteUpdateUrl"
}
@ -149,7 +149,7 @@ android {
dimension "distribution"
ext.websiteUpdateUrl = "https://github.com/oxen-io/session-android/releases"
buildConfigField "boolean", "PLAY_STORE_DISABLED", "true"
buildConfigField "String", "DEVICE", "\"android\""
buildConfigField "org.session.libsession.utilities.Device", "DEVICE", "org.session.libsession.utilities.Device.ANDROID"
buildConfigField "String", "NOPLAY_UPDATE_URL", "\"$ext.websiteUpdateUrl\""
}
}

View File

@ -1,9 +1,29 @@
package org.thoughtcrime.securesms.notifications
import android.content.Context
import com.huawei.hms.aaid.HmsInstanceId
import kotlinx.coroutines.Job
class HuaweiPushManager(val context: Context): PushManager {
override fun refresh(force: Boolean) {
private var huaweiPushInstanceIdJob: Job? = null
@Synchronized
override fun refresh(force: Boolean) {
val huaweiPushInstanceIdJob = huaweiPushInstanceIdJob
huaweiPushInstanceIdJob?.apply {
if (force) cancel() else if (isActive) return
}
val hmsInstanceId = HmsInstanceId.getInstance(context)
val task = hmsInstanceId.aaid
// HuaweiPushNotificationService().start()
//
// huaweiPushInstanceIdJob = HmsInstanceId.getInstance(this) { hmsInstanceId ->
// RegisterHuaweiPushService(hmsInstanceId, this, force).start()
// Unit.INSTANCE
// }
}
}

View File

@ -18,42 +18,19 @@ import javax.inject.Inject
@AndroidEntryPoint
class HuaweiPushNotificationService: HmsMessageService() {
@Inject token
@Inject lateinit var pushManager: PushManager
@Inject lateinit var pushHandler: PushHandler
override fun onNewToken(token: String?, bundle: Bundle?) {
Log.d("Loki", "New HCM token: $token.")
if (!token.isNullOrEmpty()) {
val userPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return
PushManager.register(token, userPublicKey, this, false)
}
pushManager.refresh(true)
}
override fun onMessageReceived(message: RemoteMessage?) {
Log.d("Loki", "Received a push notification.")
val base64EncodedData = message?.data
val data = base64EncodedData?.let { Base64.decode(it) }
if (data != null) {
try {
val envelopeAsData = MessageWrapper.unwrap(data).toByteArray()
val job = BatchMessageReceiveJob(listOf(MessageReceiveParameters(envelopeAsData)), null)
JobQueue.shared.add(job)
} catch (e: Exception) {
Log.d("Loki", "Failed to unwrap data for message due to error: $e.")
}
} else {
Log.d("Loki", "Failed to decode data for message.")
val builder = NotificationCompat.Builder(this, NotificationChannels.OTHER)
.setSmallIcon(network.loki.messenger.R.drawable.ic_notification)
.setColor(this.getResources().getColor(network.loki.messenger.R.color.textsecure_primary))
.setContentTitle("Session")
.setContentText("You've got a new message.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
with(NotificationManagerCompat.from(this)) {
notify(11111, builder.build())
}
}
pushHandler.onPush(message?.dataOfMap)
}
}
override fun onDeletedMessages() {
pushManager.refresh(true)
}
}

View File

@ -41,6 +41,7 @@ import org.session.libsession.messaging.sending_receiving.pollers.Poller;
import org.session.libsession.snode.SnodeModule;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.ConfigFactoryUpdateListener;
import org.session.libsession.utilities.Device;
import org.session.libsession.utilities.ProfilePictureUtilities;
import org.session.libsession.utilities.SSKEnvironment;
import org.session.libsession.utilities.TextSecurePreferences;
@ -142,6 +143,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
@Inject LokiAPIDatabase lokiAPIDatabase;
@Inject public Storage storage;
@Inject Device device;
@Inject MessageDataProvider messageDataProvider;
@Inject TextSecurePreferences textSecurePreferences;
@Inject PushManager pushManager;
@ -207,8 +209,10 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
DatabaseModule.init(this);
MessagingModuleConfiguration.configure(this);
super.onCreate();
messagingModuleConfiguration = new MessagingModuleConfiguration(this,
messagingModuleConfiguration = new MessagingModuleConfiguration(
this,
storage,
device,
messageDataProvider,
()-> KeyPairUtilities.INSTANCE.getUserED25519KeyPair(this),
configFactory

View File

@ -0,0 +1,16 @@
package org.thoughtcrime.securesms
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import network.loki.messenger.BuildConfig
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object DeviceModule {
@Provides
@Singleton
fun provides() = BuildConfig.DEVICE
}

View File

@ -21,6 +21,7 @@ import nl.komponents.kovenant.ui.successUi
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.messaging.sending_receiving.groupSizeLimit
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Device
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.contacts.SelectContactsAdapter
@ -31,10 +32,14 @@ import org.thoughtcrime.securesms.keyboard.emoji.KeyboardPageSearchView
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.util.fadeIn
import org.thoughtcrime.securesms.util.fadeOut
import javax.inject.Inject
@AndroidEntryPoint
class CreateGroupFragment : Fragment() {
@Inject
lateinit var device: Device
private lateinit var binding: FragmentCreateGroupBinding
private val viewModel: CreateGroupViewModel by viewModels()
@ -86,7 +91,7 @@ class CreateGroupFragment : Fragment() {
val userPublicKey = TextSecurePreferences.getLocalNumber(requireContext())!!
isLoading = true
binding.loaderContainer.fadeIn()
MessageSender.createClosedGroup(name.toString(), selectedMembers + setOf( userPublicKey )).successUi { groupID ->
MessageSender.createClosedGroup(device, name.toString(), selectedMembers + setOf( userPublicKey )).successUi { groupID ->
binding.loaderContainer.fadeOut()
isLoading = false
val threadID = DatabaseComponent.get(requireContext()).threadDatabase().getOrCreateThreadIdFor(Recipient.from(requireContext(), Address.fromSerialized(groupID), false))

View File

@ -29,24 +29,26 @@ private const val TAG = "PushHandler"
class PushHandler @Inject constructor(@ApplicationContext val context: Context) {
private val sodium = LazySodiumAndroid(SodiumAndroid())
fun onPush(dataMap: Map<String, String>) {
val data: ByteArray? = if (dataMap.containsKey("spns")) {
// this is a v2 push notification
try {
decrypt(Base64.decode(dataMap["enc_payload"]))
} catch(e: Exception) {
Log.e(TAG, "Invalid push notification: ${e.message}")
return
}
} else {
// old v1 push notification; we still need this for receiving legacy closed group notifications
dataMap.get("ENCRYPTED_DATA")?.let(Base64::decode)
}
data?.let { onPush(data) } ?: onPush()
fun onPush(dataMap: Map<String, String>?) {
onPush(dataMap?.asByteArray())
}
fun onPush() {
private fun onPush(data: ByteArray?) {
if (data == null) {
onPush()
return
}
try {
val envelopeAsData = MessageWrapper.unwrap(data).toByteArray()
val job = BatchMessageReceiveJob(listOf(MessageReceiveParameters(envelopeAsData)), null)
JobQueue.shared.add(job)
} catch (e: Exception) {
Log.d(TAG, "Failed to unwrap data for message due to error: $e.")
}
}
private fun onPush() {
Log.d(TAG, "Failed to decode data for message.")
val builder = NotificationCompat.Builder(context, NotificationChannels.OTHER)
.setSmallIcon(network.loki.messenger.R.drawable.ic_notification)
@ -58,15 +60,20 @@ class PushHandler @Inject constructor(@ApplicationContext val context: Context)
NotificationManagerCompat.from(context).notify(11111, builder.build())
}
fun onPush(data: ByteArray) {
try {
val envelopeAsData = MessageWrapper.unwrap(data).toByteArray()
val job = BatchMessageReceiveJob(listOf(MessageReceiveParameters(envelopeAsData)), null)
JobQueue.shared.add(job)
} catch (e: Exception) {
Log.d(TAG, "Failed to unwrap data for message due to error: $e.")
private fun Map<String, String>.asByteArray() =
when {
// this is a v2 push notification
containsKey("spns") -> {
try {
decrypt(Base64.decode(this["enc_payload"]))
} catch (e: Exception) {
Log.e(TAG, "Invalid push notification: ${e.message}")
null
}
}
// old v1 push notification; we still need this for receiving legacy closed group notifications
else -> this["ENCRYPTED_DATA"]?.let(Base64::decode)
}
}
fun decrypt(encPayload: ByteArray): ByteArray? {
Log.d(TAG, "decrypt() called")
@ -84,14 +91,18 @@ class PushHandler @Inject constructor(@ApplicationContext val context: Context)
val metadataJson = (expectedList[0] as? BencodeString)?.value ?: error("no metadata")
val metadata: PushNotificationMetadata = Json.decodeFromString(String(metadataJson))
val content: ByteArray? = if (expectedList.size >= 2) (expectedList[1] as? BencodeString)?.value else null
val content: ByteArray? =
if (expectedList.size >= 2) (expectedList[1] as? BencodeString)?.value else null
// null content is valid only if we got a "data_too_long" flag
if (content == null)
check(metadata.data_too_long) { "missing message data, but no too-long flag" }
else
check(metadata.data_len == content.size) { "wrong message data size" }
Log.d(TAG, "Received push for ${metadata.account}/${metadata.namespace}, msg ${metadata.msg_hash}, ${metadata.data_len}B")
Log.d(
TAG,
"Received push for ${metadata.account}/${metadata.namespace}, msg ${metadata.msg_hash}, ${metadata.data_len}B"
)
return content
}
@ -102,6 +113,11 @@ class PushHandler @Inject constructor(@ApplicationContext val context: Context)
val key = sodium.keygen(AEAD.Method.XCHACHA20_POLY1305_IETF)
IdentityKeyUtil.save(context, IdentityKeyUtil.NOTIFICATION_KEY, key.asHexString)
}
return Key.fromHexString(IdentityKeyUtil.retrieve(context, IdentityKeyUtil.NOTIFICATION_KEY))
return Key.fromHexString(
IdentityKeyUtil.retrieve(
context,
IdentityKeyUtil.NOTIFICATION_KEY
)
)
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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) {

View File

@ -5,10 +5,12 @@ import com.goterl.lazysodium.utils.KeyPair
import org.session.libsession.database.MessageDataProvider
import org.session.libsession.database.StorageProtocol
import org.session.libsession.utilities.ConfigFactoryProtocol
import org.session.libsession.utilities.Device
class MessagingModuleConfiguration(
val context: Context,
val storage: StorageProtocol,
val device: Device,
val messageDataProvider: MessageDataProvider,
val getUserED25519KeyPair: () -> KeyPair?,
val configFactory: ConfigFactoryProtocol

View File

@ -29,6 +29,7 @@ import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.SnodeMessage
import org.session.libsession.snode.SnodeModule
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Device
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsignal.crypto.PushTransportDetails
@ -454,8 +455,8 @@ object MessageSender {
}
// Closed groups
fun createClosedGroup(name: String, members: Collection<String>): Promise<String, Exception> {
return create(name, members)
fun createClosedGroup(device: Device, name: String, members: Collection<String>): Promise<String, Exception> {
return create(device, name, members)
}
fun explicitNameChange(groupPublicKey: String, newName: String) {

View File

@ -13,6 +13,7 @@ import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPol
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.Device
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
@ -33,7 +34,11 @@ const val groupSizeLimit = 100
val pendingKeyPairs = ConcurrentHashMap<String, Optional<ECKeyPair>>()
fun MessageSender.create(name: String, members: Collection<String>): Promise<String, Exception> {
fun MessageSender.create(
device: Device,
name: String,
members: Collection<String>
): Promise<String, Exception> {
val deferred = deferred<String, Exception>()
ThreadUtils.queue {
// Prepare
@ -89,7 +94,7 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
// Add the group to the config now that it was successfully created
storage.createInitialConfigGroup(groupPublicKey, name, GroupUtil.createConfigMemberMap(members, admins), sentTime, encryptionKeyPair)
// Notify the PN server
PushManagerV1.register(publicKey = userPublicKey)
PushManagerV1.register(publicKey = userPublicKey, device = device)
// Start polling
ClosedGroupPollerV2.shared.startPolling(groupPublicKey)
// Fulfill the promise

View File

@ -556,7 +556,7 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli
// Set expiration timer
storage.setExpirationTimer(groupID, expireTimer)
// Notify the PN server
PushManagerV1.register(publicKey = userPublicKey)
PushManagerV1.register(publicKey = userPublicKey, device = MessagingModuleConfiguration.shared.device)
// Notify the user
if (userPublicKey == sender && !groupExists) {
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))

View File

@ -9,6 +9,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.snode.OnionRequestAPI
import org.session.libsession.snode.OnionResponse
import org.session.libsession.snode.Version
import org.session.libsession.utilities.Device
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.JsonUtil
import org.session.libsignal.utilities.Log
@ -29,17 +30,18 @@ object PushManagerV1 {
isUsingFCM: Boolean = TextSecurePreferences.isUsingFCM(context),
token: String? = TextSecurePreferences.getFCMToken(context),
publicKey: String? = TextSecurePreferences.getLocalNumber(context),
device: Device,
legacyGroupPublicKeys: Collection<String> = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys()
): Promise<*, Exception> =
if (!isUsingFCM) {
emptyPromise()
} else retryIfNeeded(maxRetryCount) {
doRegister(token, publicKey, legacyGroupPublicKeys)
doRegister(token, publicKey, device, legacyGroupPublicKeys)
} fail { exception ->
Log.d(TAG, "Couldn't register for FCM due to error: $exception.")
}
private fun doRegister(token: String?, publicKey: String?, legacyGroupPublicKeys: Collection<String>): Promise<*, Exception> {
private fun doRegister(token: String?, publicKey: String?, device: Device, legacyGroupPublicKeys: Collection<String>): Promise<*, Exception> {
Log.d(TAG, "registerV1 requested")
token ?: return emptyPromise()
@ -48,6 +50,7 @@ object PushManagerV1 {
val parameters = mapOf(
"token" to token,
"pubKey" to publicKey,
"device" to device,
"legacyGroupPublicKeys" to legacyGroupPublicKeys
)

View File

@ -0,0 +1,6 @@
package org.session.libsession.utilities
enum class Device(val value: String) {
ANDROID("android"),
HUAWEI("huawei");
}