mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Partially implement feedback
This commit is contained in:
parent
19ec4db687
commit
742d9bfa46
@ -432,9 +432,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
public void setUpStorageAPIIfNeeded() {
|
||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this);
|
||||
if (userHexEncodedPublicKey != null && IdentityKeyUtil.hasIdentityKey(this)) {
|
||||
boolean isDebugMode = BuildConfig.DEBUG;
|
||||
byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize();
|
||||
LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this);
|
||||
boolean isDebugMode = BuildConfig.DEBUG;
|
||||
LokiStorageAPI.Companion.configure(isDebugMode, userHexEncodedPublicKey, userPrivateKey, database);
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
||||
QRCodeDialog.INSTANCE.show(getContext());
|
||||
break;
|
||||
case PREFERENCE_CATEGORY_LINK_DEVICE:
|
||||
DeviceLinkingDialog.Companion.show(getContext(), DeviceLinkingView.Mode.Master);
|
||||
DeviceLinkingDialog.Companion.show(getContext(), DeviceLinkingView.Mode.Master, null);
|
||||
break;
|
||||
case PREFERENCE_CATEGORY_SEED:
|
||||
Analytics.Companion.getShared().track("Seed Modal Shown");
|
||||
|
@ -125,7 +125,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(LokiAPIDatabase.getCreateGroupChatAuthTokenTableCommand());
|
||||
db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand());
|
||||
db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand());
|
||||
db.execSQL(LokiAPIDatabase.getCreateMultiDeviceAuthTableCommand());
|
||||
db.execSQL(LokiAPIDatabase.getCreatePairingAuthorisationTableCommand());
|
||||
db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand());
|
||||
db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand());
|
||||
db.execSQL(LokiMessageDatabase.getCreateTableCommand());
|
||||
@ -496,7 +496,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
if (oldVersion < lokiV3) {
|
||||
db.execSQL(LokiAPIDatabase.getCreateMultiDeviceAuthTableCommand());
|
||||
db.execSQL(LokiAPIDatabase.getCreatePairingAuthorisationTableCommand());
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
@ -12,14 +12,14 @@ import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
||||
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
|
||||
|
||||
class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, DeviceLinkingSessionListener {
|
||||
class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate?) : DeviceLinkingViewDelegate, DeviceLinkingSessionListener {
|
||||
private lateinit var view: DeviceLinkingView
|
||||
private lateinit var dialog: AlertDialog
|
||||
|
||||
private val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize()
|
||||
|
||||
companion object {
|
||||
fun show(context: Context, mode: DeviceLinkingView.Mode): DeviceLinkingDialog { return show(context, mode, null) }
|
||||
|
||||
fun show(context: Context, mode: DeviceLinkingView.Mode, delegate: DeviceLinkingDialogDelegate?): DeviceLinkingDialog {
|
||||
val dialog = DeviceLinkingDialog(context, mode, delegate)
|
||||
dialog.show()
|
||||
@ -27,20 +27,18 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
||||
}
|
||||
}
|
||||
|
||||
public fun dismiss() {
|
||||
this.stopListening()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
private fun show() {
|
||||
view = DeviceLinkingView(context, mode, this)
|
||||
dialog = AlertDialog.Builder(context).setView(view).show()
|
||||
view.dismiss = { dismiss() }
|
||||
|
||||
this.startListening()
|
||||
startListening()
|
||||
}
|
||||
|
||||
public fun dismiss() {
|
||||
stopListening()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
// region Private functions
|
||||
private fun startListening() {
|
||||
DeviceLinkingSession.shared.startListeningForLinkingRequests()
|
||||
DeviceLinkingSession.shared.addListener(this)
|
||||
@ -50,29 +48,20 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
||||
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||
DeviceLinkingSession.shared.removeListener(this)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Dialog View Delegate
|
||||
override fun authorise(pairing: PairingAuthorisation): Boolean {
|
||||
override fun sendPairingAuthorizedMessage(pairing: PairingAuthorisation): Boolean {
|
||||
val signedAuthorisation = pairing.sign(PairingAuthorisation.Type.GRANT, userPrivateKey)
|
||||
if (signedAuthorisation == null || signedAuthorisation.type != PairingAuthorisation.Type.GRANT) {
|
||||
Log.e("Loki", "Failed to sign grant authorisation")
|
||||
Log.d("Loki", "Failed to sign pairing authorization.")
|
||||
return false
|
||||
}
|
||||
|
||||
// Send authorisation message
|
||||
retryIfNeeded(3) {
|
||||
sendAuthorisationMessage(context, pairing.secondaryDevicePublicKey, signedAuthorisation)
|
||||
retryIfNeeded(8) {
|
||||
sendPairingAuthorisationMessage(context, pairing.secondaryDevicePublicKey, signedAuthorisation).get()
|
||||
}.fail {
|
||||
Log.e("Loki", "Failed to send GRANT authorisation to ${pairing.secondaryDevicePublicKey}")
|
||||
Log.d("Loki", "Failed to send pairing authorization message to ${pairing.secondaryDevicePublicKey}.")
|
||||
}
|
||||
|
||||
// Add the auth to the database
|
||||
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation)
|
||||
|
||||
// Update the api
|
||||
LokiStorageAPI.shared?.updateUserDeviceMappings()
|
||||
|
||||
LokiStorageAPI.shared.updateUserDeviceMappings()
|
||||
return true
|
||||
}
|
||||
|
||||
@ -81,24 +70,17 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
||||
}
|
||||
|
||||
override fun handleDeviceLinkingDialogDismissed() {
|
||||
// If we cancelled while we were listening for requests on main device, we need to remove any pre key bundles
|
||||
if (mode == DeviceLinkingView.Mode.Master && view.pairingAuthorisation != null) {
|
||||
val authorisation = view.pairingAuthorisation!!
|
||||
// Remove pre key bundle from the requesting device
|
||||
DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(authorisation.secondaryDevicePublicKey)
|
||||
}
|
||||
|
||||
delegate?.handleDeviceLinkingDialogDismissed()
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Loki Device Session Listener
|
||||
override fun requestUserAuthorization(authorisation: PairingAuthorisation) {
|
||||
Util.runOnMain {
|
||||
view.requestUserAuthorization(authorisation)
|
||||
}
|
||||
|
||||
// Stop listening to any more requests
|
||||
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||
}
|
||||
|
||||
@ -106,9 +88,6 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
||||
Util.runOnMain {
|
||||
view.onDeviceLinkAuthorized(authorisation)
|
||||
}
|
||||
|
||||
// Stop listening to any more requests
|
||||
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||
}
|
||||
// endregion
|
||||
}
|
@ -1,12 +1,6 @@
|
||||
package org.thoughtcrime.securesms.loki
|
||||
|
||||
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||
|
||||
interface DeviceLinkingDialogDelegate {
|
||||
fun handleDeviceLinkAuthorized() {}
|
||||
fun handleDeviceLinkingDialogDismissed() {}
|
||||
}
|
||||
|
||||
interface DeviceLinkingViewDelegate: DeviceLinkingDialogDelegate {
|
||||
fun authorise(pairing: PairingAuthorisation): Boolean { return false }
|
||||
fun handleDeviceLinkAuthorized() { }
|
||||
fun handleDeviceLinkingDialogDismissed() { }
|
||||
}
|
@ -5,7 +5,6 @@ import android.graphics.Color
|
||||
import android.graphics.PorterDuff
|
||||
import android.os.Handler
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import kotlinx.android.synthetic.main.view_device_linking.view.*
|
||||
@ -29,7 +28,7 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
||||
|
||||
// region Lifecycle
|
||||
constructor(context: Context, mode: Mode, delegate: DeviceLinkingViewDelegate) : this(context, null, 0, mode, delegate)
|
||||
private constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0, Mode.Master, object : DeviceLinkingViewDelegate {}) // Just pass in a dummy mode
|
||||
private constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0, Mode.Master, object : DeviceLinkingViewDelegate { }) // Just pass in a dummy mode
|
||||
private constructor(context: Context) : this(context, null)
|
||||
|
||||
init {
|
||||
@ -77,29 +76,17 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
||||
mnemonicTextView.text = MnemonicCodec(languageFileDirectory).encode(hexEncodedPublicKey).split(" ").slice(0 until 3).joinToString(" ")
|
||||
}
|
||||
authorizeButton.visibility = View.GONE
|
||||
authorizeButton.setOnClickListener { authorize() }
|
||||
authorizeButton.setOnClickListener { authorizePairing() }
|
||||
cancelButton.setOnClickListener { cancel() }
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Device Linking
|
||||
fun requestUserAuthorization(authorisation: PairingAuthorisation) {
|
||||
// To be called when a linking request has been received
|
||||
if (mode != Mode.Master) {
|
||||
Log.w("Loki", "Received request for pairing authorisation on a slave device")
|
||||
return
|
||||
}
|
||||
|
||||
if (authorisation.type != PairingAuthorisation.Type.REQUEST) {
|
||||
Log.w("Loki", "Received request for GRANT pairing authorisation! It shouldn't be possible!!")
|
||||
return
|
||||
}
|
||||
|
||||
if (this.pairingAuthorisation != null) {
|
||||
Log.e("Loki", "Received request for another pairing authorisation when one was active")
|
||||
return
|
||||
}
|
||||
|
||||
if (mode != Mode.Master) { throw IllegalStateException() }
|
||||
if (authorisation.type != PairingAuthorisation.Type.REQUEST) { throw IllegalStateException() }
|
||||
if (pairingAuthorisation != null) { return }
|
||||
pairingAuthorisation = authorisation
|
||||
spinner.visibility = View.GONE
|
||||
val titleTextViewLayoutParams = titleTextView.layoutParams as LayoutParams
|
||||
titleTextViewLayoutParams.topMargin = toPx(16, resources)
|
||||
@ -110,25 +97,11 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
||||
val hexEncodedPublicKey = authorisation.secondaryDevicePublicKey.removing05PrefixIfNeeded()
|
||||
mnemonicTextView.text = MnemonicCodec(languageFileDirectory).encode(hexEncodedPublicKey).split(" ").slice(0 until 3).joinToString(" ")
|
||||
authorizeButton.visibility = View.VISIBLE
|
||||
|
||||
this.pairingAuthorisation = authorisation
|
||||
}
|
||||
|
||||
private fun authorize() {
|
||||
if (pairingAuthorisation == null || mode != Mode.Master ) { return; }
|
||||
|
||||
// Pass authorisation to delegate and only dismiss if it succeeded
|
||||
if (delegate.authorise(pairingAuthorisation!!)) {
|
||||
delegate.handleDeviceLinkAuthorized()
|
||||
dismiss?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDeviceLinkAuthorized(authorisation: PairingAuthorisation) {
|
||||
// To be called when a device link was accepted by the primary device
|
||||
if (mode == Mode.Master || pairingAuthorisation != null) { return }
|
||||
if (mode != Mode.Slave || pairingAuthorisation != null) { return }
|
||||
pairingAuthorisation = authorisation
|
||||
|
||||
spinner.visibility = View.GONE
|
||||
val titleTextViewLayoutParams = titleTextView.layoutParams as LayoutParams
|
||||
titleTextViewLayoutParams.topMargin = toPx(8, resources)
|
||||
@ -142,7 +115,6 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
||||
mnemonicTextView.visibility = View.GONE
|
||||
buttonContainer.visibility = View.GONE
|
||||
cancelButton.visibility = View.GONE
|
||||
|
||||
Handler().postDelayed({
|
||||
delegate.handleDeviceLinkAuthorized()
|
||||
dismiss?.invoke()
|
||||
@ -151,6 +123,14 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
private fun authorizePairing() {
|
||||
if (pairingAuthorisation == null || mode != Mode.Master ) { return; }
|
||||
if (delegate.sendPairingAuthorizedMessage(pairingAuthorisation!!)) {
|
||||
delegate.handleDeviceLinkAuthorized()
|
||||
dismiss?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancel() {
|
||||
delegate.handleDeviceLinkingDialogDismissed()
|
||||
dismiss?.invoke()
|
||||
|
@ -0,0 +1,9 @@
|
||||
package org.thoughtcrime.securesms.loki
|
||||
|
||||
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||
|
||||
interface DeviceLinkingViewDelegate {
|
||||
fun handleDeviceLinkAuthorized() { }
|
||||
fun handleDeviceLinkingDialogDismissed() { }
|
||||
fun sendPairingAuthorizedMessage(pairing: PairingAuthorisation): Boolean { return false }
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
package org.thoughtcrime.securesms.loki
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.support.annotation.ColorRes
|
||||
import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun Resources.getColorWithID(@ColorRes id: Int, theme: Resources.Theme?): Int {
|
||||
@ -16,4 +22,20 @@ fun Resources.getColorWithID(@ColorRes id: Int, theme: Resources.Theme?): Int {
|
||||
fun toPx(dp: Int, resources: Resources): Int {
|
||||
val scale = resources.displayMetrics.density
|
||||
return (dp * scale).roundToInt()
|
||||
}
|
||||
|
||||
fun isGroupRecipient(recipient: String): Boolean {
|
||||
return (LokiGroupChatAPI.publicChatServer == recipient)
|
||||
}
|
||||
|
||||
fun getFriendPublicKeys(context: Context, devicePublicKeys: Set<String>): Set<String> {
|
||||
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
|
||||
return devicePublicKeys.mapNotNull { device ->
|
||||
val address = Address.fromSerialized(device)
|
||||
val recipient = Recipient.from(context, address, false)
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient)
|
||||
if (threadID < 0) { return@mapNotNull null }
|
||||
val friendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID)
|
||||
if (friendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS) device else null
|
||||
}.toSet()
|
||||
}
|
@ -47,14 +47,14 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
||||
private val lastDeletionServerIDCacheIndex = "loki_api_last_deletion_server_id_cache_index"
|
||||
private val lastDeletionServerID = "last_deletion_server_id"
|
||||
@JvmStatic val createLastDeletionServerIDTableCommand = "CREATE TABLE $lastDeletionServerIDCache ($lastDeletionServerIDCacheIndex STRING PRIMARY KEY, $lastDeletionServerID INTEGER DEFAULT 0);"
|
||||
|
||||
// Authorisation
|
||||
private val multiDeviceAuthTable = "loki_multi_device_authorisation"
|
||||
private val primaryDevice = "primary_device"
|
||||
private val secondaryDevice = "secondary_device"
|
||||
// Pairing authorisation cache
|
||||
private val pairingAuthorisationCache = "loki_pairing_authorisation_cache"
|
||||
private val primaryDevicePublicKey = "primary_device"
|
||||
private val secondaryDevicePublicKey = "secondary_device"
|
||||
private val requestSignature = "request_signature"
|
||||
private val grantSignature = "grant_signature"
|
||||
@JvmStatic val createMultiDeviceAuthTableCommand = "CREATE TABLE $multiDeviceAuthTable($primaryDevice TEXT, $secondaryDevice TEXT, $requestSignature TEXT NULLABLE DEFAULT NULL, $grantSignature TEXT NULLABLE DEFAULT NULL, PRIMARY KEY ($primaryDevice, $secondaryDevice));"
|
||||
@JvmStatic val createPairingAuthorisationTableCommand = "CREATE TABLE $pairingAuthorisationCache ($primaryDevicePublicKey TEXT, $secondaryDevicePublicKey TEXT, " +
|
||||
"$requestSignature TEXT NULLABLE DEFAULT NULL, $grantSignature TEXT NULLABLE DEFAULT NULL, PRIMARY KEY ($primaryDevicePublicKey, $secondaryDevicePublicKey));"
|
||||
}
|
||||
|
||||
override fun getSwarmCache(hexEncodedPublicKey: String): Set<LokiAPITarget>? {
|
||||
@ -154,9 +154,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
||||
|
||||
override fun getPairingAuthorisations(hexEncodedPublicKey: String): List<PairingAuthorisation> {
|
||||
val database = databaseHelper.readableDatabase
|
||||
return database.getAll(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey)) { cursor ->
|
||||
val primaryDevicePubKey = cursor.getString(primaryDevice)
|
||||
val secondaryDevicePubKey = cursor.getString(secondaryDevice)
|
||||
return database.getAll(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) { cursor ->
|
||||
val primaryDevicePubKey = cursor.getString(primaryDevicePublicKey)
|
||||
val secondaryDevicePubKey = cursor.getString(secondaryDevicePublicKey)
|
||||
val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature)
|
||||
val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature)
|
||||
PairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature)
|
||||
@ -166,16 +166,16 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
||||
override fun insertOrUpdatePairingAuthorisation(authorisation: PairingAuthorisation) {
|
||||
val database = databaseHelper.writableDatabase
|
||||
val values = ContentValues()
|
||||
values.put(primaryDevice, authorisation.primaryDevicePublicKey)
|
||||
values.put(secondaryDevice, authorisation.secondaryDevicePublicKey)
|
||||
values.put(primaryDevicePublicKey, authorisation.primaryDevicePublicKey)
|
||||
values.put(secondaryDevicePublicKey, authorisation.secondaryDevicePublicKey)
|
||||
if (authorisation.requestSignature != null) { values.put(requestSignature, Base64.encodeBytes(authorisation.requestSignature)) }
|
||||
if (authorisation.grantSignature != null) { values.put(grantSignature, Base64.encodeBytes(authorisation.grantSignature)) }
|
||||
database.insertOrUpdate(multiDeviceAuthTable, values, "$primaryDevice = ? AND $secondaryDevice = ?", arrayOf(authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey))
|
||||
database.insertOrUpdate(pairingAuthorisationCache, values, "$primaryDevicePublicKey = ? AND $secondaryDevicePublicKey = ?", arrayOf( authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey ))
|
||||
}
|
||||
|
||||
override fun removePairingAuthorisations(hexEncodedPublicKey: String) {
|
||||
val database = databaseHelper.readableDatabase
|
||||
database.delete(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey))
|
||||
database.delete(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey ))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI,
|
||||
devices.remove(ourPubKey)
|
||||
}
|
||||
|
||||
val friends = getFriends(context, devices)
|
||||
val friends = getFriendPublicKeys(context, devices)
|
||||
for (device in devices) {
|
||||
block(device, friends.contains(device), friends.count())
|
||||
}
|
||||
@ -80,7 +80,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
|
||||
return deferred.promise
|
||||
}
|
||||
|
||||
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise<Unit, Exception> {
|
||||
fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise<Unit, Exception> {
|
||||
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
||||
val address = SignalServiceAddress(contactHexEncodedPublicKey)
|
||||
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
|
||||
|
@ -233,7 +233,7 @@ class SeedActivity : BaseActionBarActivity() {
|
||||
// Send the request to the other user
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
retryIfNeeded(3) {
|
||||
sendAuthorisationMessage(this@SeedActivity, authorisation.primaryDevicePublicKey, authorisation).get()
|
||||
sendPairingAuthorisationMessage(this@SeedActivity, authorisation.primaryDevicePublicKey, authorisation).get()
|
||||
}.failUi {
|
||||
dialog.dismiss()
|
||||
resetRegistration()
|
||||
|
@ -1,25 +0,0 @@
|
||||
package org.thoughtcrime.securesms.loki
|
||||
|
||||
import android.content.Context
|
||||
import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||
|
||||
fun isGroupChat(pubKey: String): Boolean {
|
||||
return (LokiGroupChatAPI.publicChatServer == pubKey)
|
||||
}
|
||||
|
||||
fun getFriends(context: Context, devices: Set<String>): Set<String> {
|
||||
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
|
||||
|
||||
return devices.mapNotNull { device ->
|
||||
val address = Address.fromSerialized(device)
|
||||
val recipient = Recipient.from(context, address, false)
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient)
|
||||
if (threadID < 0) { return@mapNotNull null }
|
||||
|
||||
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) device else null
|
||||
}.toSet()
|
||||
}
|
@ -20,11 +20,9 @@ import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.SendReadReceiptJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilKt;
|
||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -91,20 +89,13 @@ public class MarkReadReceiver extends BroadcastReceiver {
|
||||
|
||||
for (Address address : addressMap.keySet()) {
|
||||
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
|
||||
if (storageAPI == null) {
|
||||
Log.w("Loki", "LokiStorageAPI is not initialized!");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Long> timestamps = Stream.of(addressMap.get(address)).map(SyncMessageId::getTimetamp).toList();
|
||||
|
||||
MultiDeviceUtilKt.getAllDevices(context, address.serialize(), storageAPI, (devicePubKey, isFriend, friendCount) -> {
|
||||
MultiDeviceUtilKt.getAllDevices(context, address.serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> {
|
||||
// Loki - This also prevents read receipts from being sent in group chats as they don't maintain a friend request status
|
||||
if (isFriend) {
|
||||
Address deviceAddress = Address.fromSerialized(devicePubKey);
|
||||
ApplicationContext.getInstance(context)
|
||||
.getJobManager()
|
||||
.add(new SendReadReceiptJob(deviceAddress, timestamps));
|
||||
ApplicationContext.getInstance(context).getJobManager().add(new SendReadReceiptJob(Address.fromSerialized(devicePublicKey), timestamps));
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
@ -42,8 +42,8 @@ import org.thoughtcrime.securesms.jobs.SmsSendJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.GeneralUtilitiesKt;
|
||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilKt;
|
||||
import org.thoughtcrime.securesms.loki.UtilKt;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
||||
@ -211,27 +211,26 @@ public class MessageSender {
|
||||
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
|
||||
JobManager jobManager = ApplicationContext.getInstance(context).getJobManager();
|
||||
|
||||
// Just send the message normally if the storage api is not set or if it's a group message
|
||||
String recipientPubKey = recipient.getAddress().serialize();
|
||||
if (storageAPI == null || UtilKt.isGroupChat(recipientPubKey)) {
|
||||
if (storageAPI == null) { Log.w("Loki", "LokiStorageAPI is not initialized!"); }
|
||||
// Just send the message normally if it's a group message
|
||||
String recipientPublicKey = recipient.getAddress().serialize();
|
||||
if (GeneralUtilitiesKt.isGroupRecipient(recipientPublicKey)) {
|
||||
jobManager.add(new PushTextSendJob(messageId, recipient.getAddress()));
|
||||
return;
|
||||
}
|
||||
|
||||
MultiDeviceUtilKt.getAllDevices(context, recipientPubKey, storageAPI, (devicePubKey, isFriend, friendCount) -> {
|
||||
Address deviceAddress = Address.fromSerialized(devicePubKey);
|
||||
long messageIdToUse = recipientPubKey.equals(devicePubKey) ? messageId : -1L;
|
||||
MultiDeviceUtilKt.getAllDevices(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> {
|
||||
Address address = Address.fromSerialized(devicePublicKey);
|
||||
long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L;
|
||||
|
||||
// Send a normal message to our friends
|
||||
if (isFriend) {
|
||||
jobManager.add(new PushTextSendJob(messageId, messageIdToUse, deviceAddress));
|
||||
// Send a normal message if the user is friends with the recipient
|
||||
jobManager.add(new PushTextSendJob(messageId, messageIDToUse, address));
|
||||
} else {
|
||||
// Send friend requests to non friends
|
||||
// If we're friends with one of the devices then send out a default friend request message
|
||||
boolean isFriendsWithAny = friendCount > 0;
|
||||
String defaultFriendRequestMessage = isFriendsWithAny ? "This is a friend request for devices linked to " + recipientPubKey : null;
|
||||
jobManager.add(new PushTextSendJob(messageId, messageIdToUse, deviceAddress, true, defaultFriendRequestMessage));
|
||||
// Send friend requests to non friends. If the user is friends with any
|
||||
// of the devices then send out a default friend request message.
|
||||
boolean isFriendsWithAny = (friendCount > 0);
|
||||
String defaultFriendRequestMessage = isFriendsWithAny ? "Accept this friend request to enable messages to be synced across devices" : null;
|
||||
jobManager.add(new PushTextSendJob(messageId, messageIDToUse, address, true, defaultFriendRequestMessage));
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
@ -242,26 +241,26 @@ public class MessageSender {
|
||||
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
|
||||
JobManager jobManager = ApplicationContext.getInstance(context).getJobManager();
|
||||
|
||||
// Just send the message normally if the storage api is not set or if it's a group message
|
||||
String recipientPubKey = recipient.getAddress().serialize();
|
||||
if (storageAPI == null || UtilKt.isGroupChat(recipientPubKey)) {
|
||||
if (storageAPI == null) { Log.w("Loki", "LokiStorageAPI is not initialized!"); }
|
||||
// Just send the message normally if it's a group message
|
||||
String recipientPublicKey = recipient.getAddress().serialize();
|
||||
if (GeneralUtilitiesKt.isGroupRecipient(recipientPublicKey)) {
|
||||
PushMediaSendJob.enqueue(context, jobManager, messageId, recipient.getAddress());
|
||||
return;
|
||||
}
|
||||
|
||||
MultiDeviceUtilKt.getAllDevices(context, recipientPubKey, storageAPI, (devicePubKey, isFriend, friendCount) -> {
|
||||
Address deviceAddress = Address.fromSerialized(devicePubKey);
|
||||
long messageIdToUse = recipientPubKey.equals(devicePubKey) ? messageId : -1L;
|
||||
MultiDeviceUtilKt.getAllDevices(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> {
|
||||
Address address = Address.fromSerialized(devicePublicKey);
|
||||
long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L;
|
||||
|
||||
// Send a normal message to our friends
|
||||
if (isFriend) {
|
||||
PushMediaSendJob.enqueue(context, jobManager, messageId, messageIdToUse, deviceAddress);
|
||||
// Send a normal message if the user is friends with the recipient
|
||||
PushMediaSendJob.enqueue(context, jobManager, messageId, messageIDToUse, address);
|
||||
} else {
|
||||
// Send friend requests to non friends
|
||||
// If we're friends with one of the devices then send out a default friend request message
|
||||
// Send friend requests to non friends. If the user is friends with any
|
||||
// of the devices then send out a default friend request message.
|
||||
boolean isFriendsWithAny = friendCount > 0;
|
||||
String defaultFriendRequestMessage = isFriendsWithAny ? "This is a friend request for devices linked to " + recipientPubKey : null;
|
||||
PushMediaSendJob.enqueue(context, jobManager, messageId, messageIdToUse, deviceAddress, true, defaultFriendRequestMessage);
|
||||
String defaultFriendRequestMessage = isFriendsWithAny ? "Accept this friend request to enable messages to be synced across devices" : null;
|
||||
PushMediaSendJob.enqueue(context, jobManager, messageId, messageIDToUse, address, true, defaultFriendRequestMessage);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user