diff --git a/res/layout/fragment_key_pair_migration_bottom_sheet.xml b/res/layout/fragment_key_pair_migration_bottom_sheet.xml
new file mode 100644
index 0000000000..4ff5e57327
--- /dev/null
+++ b/res/layout/fragment_key_pair_migration_bottom_sheet.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java
index c40c330c34..20dbd7e6f6 100644
--- a/src/org/thoughtcrime/securesms/ApplicationContext.java
+++ b/src/org/thoughtcrime/securesms/ApplicationContext.java
@@ -588,7 +588,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
});
}
- public void clearData() {
+ public void clearAllData() {
String token = TextSecurePreferences.getFCMToken(this);
if (token != null && !token.isEmpty()) {
LokiPushNotificationManager.unregister(token, this);
diff --git a/src/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
index f6e28336b4..3d10e33ee4 100644
--- a/src/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
@@ -6,8 +6,6 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.Cursor
-import android.net.Uri
-import android.os.AsyncTask
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
@@ -31,14 +29,9 @@ import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.ConversationActivity
import org.thoughtcrime.securesms.database.DatabaseFactory
-import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord
-import org.thoughtcrime.securesms.groups.GroupManager
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
-import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet
-import org.thoughtcrime.securesms.loki.dialogs.LightThemeFeatureIntroBottomSheet
-import org.thoughtcrime.securesms.loki.dialogs.MultiDeviceRemovalBottomSheet
-import org.thoughtcrime.securesms.loki.dialogs.UserDetailsBottomSheet
+import org.thoughtcrime.securesms.loki.dialogs.*
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
import org.thoughtcrime.securesms.loki.utilities.*
@@ -57,6 +50,7 @@ import org.whispersystems.signalservice.loki.protocol.shelved.multidevice.MultiD
import org.whispersystems.signalservice.loki.protocol.shelved.syncmessages.SyncMessagesProtocol
import org.whispersystems.signalservice.loki.utilities.toHexString
import java.io.IOException
+import java.util.*
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate {
private lateinit var glide: GlideRequests
@@ -178,7 +172,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
// Clear all data if this is a secondary device
if (TextSecurePreferences.getMasterHexEncodedPublicKey(this) != null) {
TextSecurePreferences.setWasUnlinked(this, true)
- ApplicationContext.getInstance(this).clearData()
+ ApplicationContext.getInstance(this).clearAllData()
}
}
@@ -191,36 +185,15 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
if (hasViewedSeed || !isMasterDevice) {
seedReminderView.visibility = View.GONE
}
-
- // Multi device removal sheet
- if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) {
- TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this)
- val userPublicKey = TextSecurePreferences.getLocalNumber(this)
- val deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userPublicKey)
- if (deviceLinks.isNotEmpty()) {
- val bottomSheet = MultiDeviceRemovalBottomSheet()
- bottomSheet.onOKTapped = {
- bottomSheet.dismiss()
- }
- bottomSheet.onLinkTapped = {
- bottomSheet.dismiss()
- val url = "https://getsession.org/faq"
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- startActivity(intent)
- }
- bottomSheet.show(supportFragmentManager, bottomSheet.tag)
- return
- }
- }
-
- // Light theme introduction sheet
- if (!TextSecurePreferences.hasSeenLightThemeIntroSheet(this) &&
- UiModeUtilities.isDayUiMode(this)) {
- TextSecurePreferences.setHasSeenLightThemeIntroSheet(this)
- val bottomSheet = LightThemeFeatureIntroBottomSheet()
- bottomSheet.show(supportFragmentManager, bottomSheet.tag)
- return
- }
+ // Show key pair migration sheet if needed
+ if (KeyPairUtilities.hasV2KeyPair(this)) { return }
+ val lastNudge = TextSecurePreferences.getLastKeyPairMigrationNudge(this)
+ val nudgeInterval: Long = 3 * 24 * 60 * 60 * 1000 // 3 days
+ val nudge = (Date().time - lastNudge > nudgeInterval)
+ if (!nudge) { return }
+ val keyPairMigrationSheet = KeyPairMigrationBottomSheet()
+ keyPairMigrationSheet.show(supportFragmentManager, keyPairMigrationSheet.tag)
+ TextSecurePreferences.setLastKeyPairMigrationNudge(this, Date().time)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/src/org/thoughtcrime/securesms/loki/api/SessionProtocol.kt b/src/org/thoughtcrime/securesms/loki/api/SessionProtocolImpl.kt
similarity index 100%
rename from src/org/thoughtcrime/securesms/loki/api/SessionProtocol.kt
rename to src/org/thoughtcrime/securesms/loki/api/SessionProtocolImpl.kt
diff --git a/src/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt b/src/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt
index 50e54567b9..fb0d4ad151 100644
--- a/src/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt
+++ b/src/org/thoughtcrime/securesms/loki/dialogs/ClearAllDataDialog.kt
@@ -27,13 +27,13 @@ class ClearAllDataDialog : DialogFragment() {
private fun clearAllData() {
if (KeyPairUtilities.hasV2KeyPair(requireContext())) {
- ApplicationContext.getInstance(context).clearData()
+ ApplicationContext.getInstance(context).clearAllData()
} else {
val dialog = AlertDialog.Builder(requireContext())
val message = "We’ve upgraded the way Session IDs are generated, so you will be unable to restore your current Session ID."
dialog.setMessage(message)
dialog.setPositiveButton("Yes") { _, _ ->
- ApplicationContext.getInstance(context).clearData()
+ ApplicationContext.getInstance(context).clearAllData()
}
dialog.setNegativeButton("Cancel") { _, _ ->
// Do nothing
diff --git a/src/org/thoughtcrime/securesms/loki/dialogs/KeyPairMigrationBottomSheet.kt b/src/org/thoughtcrime/securesms/loki/dialogs/KeyPairMigrationBottomSheet.kt
new file mode 100644
index 0000000000..ede0e74d55
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/loki/dialogs/KeyPairMigrationBottomSheet.kt
@@ -0,0 +1,53 @@
+package org.thoughtcrime.securesms.loki.dialogs
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import com.google.android.material.bottomsheet.BottomSheetBehavior
+import com.google.android.material.bottomsheet.BottomSheetDialog
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import kotlinx.android.synthetic.main.fragment_key_pair_migration_bottom_sheet.*
+import network.loki.messenger.R
+import org.thoughtcrime.securesms.ApplicationContext
+
+class KeyPairMigrationBottomSheet : BottomSheetDialogFragment() {
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.fragment_key_pair_migration_bottom_sheet, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ upgradeNowButton.setOnClickListener { upgradeNow() }
+ upgradeLaterButton.setOnClickListener { dismiss() }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val dialog = super.onCreateDialog(savedInstanceState)
+ // Expand the bottom sheet by default
+ dialog.setOnShowListener {
+ val d = dialog as BottomSheetDialog
+ val bottomSheet = d.findViewById(com.google.android.material.R.id.design_bottom_sheet)
+ BottomSheetBehavior.from(bottomSheet!!).setState(BottomSheetBehavior.STATE_EXPANDED);
+ }
+ return dialog
+ }
+
+ private fun upgradeNow() {
+ val applicationContext = requireContext().applicationContext as ApplicationContext
+ dismiss()
+ val dialog = AlertDialog.Builder(requireContext())
+ dialog.setMessage("You’re upgrading to a new Session ID. This will give you improved privacy and security, but it will clear ALL app data. Contacts and conversations will be lost. Proceed?")
+ dialog.setPositiveButton(R.string.yes) { _, _ ->
+ applicationContext.clearAllData()
+ }
+ dialog.setNegativeButton(R.string.cancel) { _, _ ->
+ // Do nothing
+ }
+ dialog.create().show()
+ }
+}
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt
index 130dd2b9b3..4f37c49c73 100644
--- a/src/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt
+++ b/src/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt
@@ -197,7 +197,7 @@ object MultiDeviceProtocol {
FileServerAPI.shared.removeDeviceLink(slaveDeviceLink) // Attempt to clean up on the file server
}
TextSecurePreferences.setWasUnlinked(context, true)
- ApplicationContext.getInstance(context).clearData()
+ ApplicationContext.getInstance(context).clearAllData()
}
}
}
diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index 4787b48cf8..2069274cd7 100644
--- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -1342,5 +1342,13 @@ public class TextSecurePreferences {
public static void setLastSnodePoolRefreshDate(Context context, Date date) {
setLongPreference(context, "last_snode_pool_refresh_date", date.getTime());
}
+
+ public static long getLastKeyPairMigrationNudge(Context context) {
+ return getLongPreference(context, "last_key_pair_migration_nudge", 0);
+ }
+
+ public static void setLastKeyPairMigrationNudge(Context context, long newValue) {
+ setLongPreference(context, "last_key_pair_migration_nudge", newValue);
+ }
// endregion
}