Show toast if message sending failed.

Added resetting
This commit is contained in:
Mikunj 2019-10-02 12:20:18 +10:00
parent 373b9b38f6
commit 72059328b3
6 changed files with 76 additions and 23 deletions

View File

@ -141,6 +141,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
// LokiStorageAPI.Companion.setDebugMode(BuildConfig.DEBUG);
LokiGroupChatAPI.Companion.setDebugMode(BuildConfig.DEBUG); // Loki - Set debug mode if needed LokiGroupChatAPI.Companion.setDebugMode(BuildConfig.DEBUG); // Loki - Set debug mode if needed
startKovenant(); startKovenant();
Log.i(TAG, "onCreate()"); Log.i(TAG, "onCreate()");

View File

@ -172,8 +172,7 @@ public class IdentityKeyUtil {
if (!preferencesEditor.commit()) throw new AssertionError("failed to save identity key/value to shared preferences"); if (!preferencesEditor.commit()) throw new AssertionError("failed to save identity key/value to shared preferences");
} }
private static void delete(Context context, String key) { public static void delete(Context context, String key) {
context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0).edit().remove(key).commit(); context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0).edit().remove(key).commit();
} }
} }

View File

@ -9,27 +9,32 @@ import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSessionListener import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSessionListener
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
import org.whispersystems.signalservice.loki.api.LokiStorageAPI import org.whispersystems.signalservice.loki.api.LokiStorageAPI
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, LokiDeviceLinkingSessionListener { class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, LokiDeviceLinkingSessionListener {
private lateinit var view: DeviceLinkingView private lateinit var view: DeviceLinkingView
private lateinit var dialog: AlertDialog
private val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() private val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize()
companion object { companion object {
fun show(context: Context, mode: DeviceLinkingView.Mode) { show(context, mode, null) } fun show(context: Context, mode: DeviceLinkingView.Mode): DeviceLinkingDialog { return show(context, mode, null) }
fun show(context: Context, mode: DeviceLinkingView.Mode, delegate: DeviceLinkingDialogDelegate?) { fun show(context: Context, mode: DeviceLinkingView.Mode, delegate: DeviceLinkingDialogDelegate?): DeviceLinkingDialog {
val dialog = DeviceLinkingDialog(context, mode, delegate) val dialog = DeviceLinkingDialog(context, mode, delegate)
dialog.show() dialog.show()
return dialog
} }
} }
public fun dismiss() {
this.stopListening()
dialog.dismiss()
}
private fun show() { private fun show() {
view = DeviceLinkingView(context, mode, this) view = DeviceLinkingView(context, mode, this)
val dialog = AlertDialog.Builder(context).setView(view).show() dialog = AlertDialog.Builder(context).setView(view).show()
view.dismiss = { view.dismiss = { dismiss() }
this.stopListening()
dialog.dismiss()
}
this.startListening() this.startListening()
} }
@ -55,7 +60,11 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
} }
// Send authorisation message // Send authorisation message
sendAuthorisationMessage(context, pairing.secondaryDevicePubKey, signedAuthorisation) retryIfNeeded(3) {
sendAuthorisationMessage(context, pairing.secondaryDevicePubKey, signedAuthorisation)
}.fail {
Log.e("Loki", "Failed to send GRANT authorisation to ${pairing.secondaryDevicePubKey}")
}
// Add the auth to the database // Add the auth to the database
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation) DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation)

View File

@ -9,7 +9,11 @@ import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_seed.* import kotlinx.android.synthetic.main.activity_seed.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import network.loki.messenger.R import network.loki.messenger.R
import nl.komponents.kovenant.ui.failUi
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
@ -26,6 +30,7 @@ import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import org.whispersystems.signalservice.loki.utilities.Analytics import org.whispersystems.signalservice.loki.utilities.Analytics
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -209,22 +214,31 @@ class SeedActivity : BaseActionBarActivity() {
val application = ApplicationContext.getInstance(this) val application = ApplicationContext.getInstance(this)
application.startLongPollingIfNeeded() application.startLongPollingIfNeeded()
application.setUpP2PAPI()
application.setUpStorageAPIIfNeeded() application.setUpStorageAPIIfNeeded()
// Show the dialog // Show the dialog
DeviceLinkingDialog.show(this, DeviceLinkingView.Mode.Slave, object: DeviceLinkingDialogDelegate { val dialog = DeviceLinkingDialog.show(this, DeviceLinkingView.Mode.Slave, object: DeviceLinkingDialogDelegate {
override fun handleDeviceLinkAuthorized() { override fun handleDeviceLinkAuthorized() {
showAccountDetailsView() showAccountDetailsView()
} }
override fun handleDeviceLinkingDialogDismissed() { override fun handleDeviceLinkingDialogDismissed() {
resetRegistration() resetRegistration()
Toast.makeText(application, "Cancelled Device Linking", Toast.LENGTH_SHORT).show() Toast.makeText(this@SeedActivity, "Cancelled Device Linking", Toast.LENGTH_SHORT).show()
} }
}) })
// Send the request to the other user // Send the request to the other user
sendAuthorisationMessage(this, authorisation.primaryDevicePubKey, authorisation) CoroutineScope(Dispatchers.Main).launch {
retryIfNeeded(3) {
sendAuthorisationMessage(this@SeedActivity, authorisation.primaryDevicePubKey, authorisation)
}.failUi {
dialog.dismiss()
resetRegistration()
Toast.makeText(application, "Failed to send device pairing request. Please try again.", Toast.LENGTH_SHORT).show()
}
}
} else { } else {
showAccountDetailsView() showAccountDetailsView()
} }
@ -236,7 +250,11 @@ class SeedActivity : BaseActionBarActivity() {
} }
private fun resetRegistration() { private fun resetRegistration() {
IdentityKeyUtil.delete(this, IdentityKeyUtil.lokiSeedKey)
TextSecurePreferences.removeLocalRegistrationId(this)
TextSecurePreferences.removeLocalNumber(this)
TextSecurePreferences.setHasSeenWelcomeScreen(this, false)
TextSecurePreferences.setPromptedPushRegistration(this, false)
} }
// endregion // endregion
} }

View File

@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.loki
import android.content.Context import android.content.Context
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.logging.Log
import org.whispersystems.libsignal.util.guava.Optional import org.whispersystems.libsignal.util.guava.Optional
@ -11,15 +13,31 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: LokiPairingAuthorisation) { fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: LokiPairingAuthorisation): Promise<Unit, Exception> {
val deferred = deferred<Unit, Exception>()
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
val address = SignalServiceAddress(contactHexEncodedPublicKey) val address = SignalServiceAddress(contactHexEncodedPublicKey)
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation).build() // A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message.
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation).asFriendRequest(authorisation.type == LokiPairingAuthorisation.Type.REQUEST).build()
try { try {
messageSender.sendMessage(0, address, Optional.absent<UnidentifiedAccessPair>(), message) // The message ID doesn't matter Log.d("Loki", "Sending authorisation message to $contactHexEncodedPublicKey")
val result = messageSender.sendMessage(0, address, Optional.absent<UnidentifiedAccessPair>(), message)
if (result.success == null) {
val exception = when {
result.isNetworkFailure -> "Failed to send authorisation message because of a Network Error"
else -> "Failed to send authorisation message"
}
throw Exception(exception)
}
deferred.resolve(Unit)
} catch (e: Exception) { } catch (e: Exception) {
Log.d("Loki", "Failed to send authorisation message to: $contactHexEncodedPublicKey.") Log.d("Loki", "Failed to send authorisation message to: $contactHexEncodedPublicKey.")
deferred.reject(e)
} }
} }
return deferred.promise
} }

View File

@ -546,6 +546,10 @@ public class TextSecurePreferences {
setIntegerPrefrence(context, LOCAL_REGISTRATION_ID_PREF, registrationId); setIntegerPrefrence(context, LOCAL_REGISTRATION_ID_PREF, registrationId);
} }
public static void removeLocalRegistrationId(Context context) {
removePreference(context, LOCAL_REGISTRATION_ID_PREF);
}
public static boolean isInThreadNotifications(Context context) { public static boolean isInThreadNotifications(Context context) {
return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true); return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true);
} }
@ -639,6 +643,10 @@ public class TextSecurePreferences {
setStringPreference(context, LOCAL_NUMBER_PREF, localNumber); setStringPreference(context, LOCAL_NUMBER_PREF, localNumber);
} }
public static void removeLocalNumber(Context context) {
removePreference(context, LOCAL_NUMBER_PREF);
}
public static String getPushServerPassword(Context context) { public static String getPushServerPassword(Context context) {
return getStringPreference(context, GCM_PASSWORD_PREF, null); return getStringPreference(context, GCM_PASSWORD_PREF, null);
} }