Recommend that users migrate

This commit is contained in:
Niels Andriesse
2020-12-16 13:55:05 +11:00
parent 48477a72ba
commit 3f6daf2226
8 changed files with 136 additions and 43 deletions

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:padding="@dimen/large_spacing"
app:behavior_hideable="true"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_sun"
android:tint="?android:textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="Session IDs Just Got Better"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="Weve upgraded Session IDs to make them even more private and secure. We recommend upgrading to a new Session ID now."
android:textSize="@dimen/medium_font_size"
android:textAlignment="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_spacing"
android:text="You will lose existing contacts and conversations, but youll gain even more privacy and security. You will need to upgrade your Session ID eventually, but you can choose to delay the upgrade if you need to save contacts or conversations."
android:textSize="@dimen/medium_font_size"
android:textAlignment="center" />
<Button
style="@style/Widget.Session.Button.Common.UnimportantOutline"
android:id="@+id/upgradeNowButton"
android:layout_width="240dp"
android:layout_height="@dimen/medium_button_height"
android:layout_marginTop="@dimen/very_large_spacing"
android:text="Upgrade Now" />
<Button
style="@style/Widget.Session.Button.Common.UnimportantOutline"
android:id="@+id/upgradeLaterButton"
android:layout_width="240dp"
android:layout_height="@dimen/medium_button_height"
android:layout_marginTop="@dimen/medium_spacing"
android:text="Upgrade Later" />
</LinearLayout>

View File

@@ -588,7 +588,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
}); });
} }
public void clearData() { public void clearAllData() {
String token = TextSecurePreferences.getFCMToken(this); String token = TextSecurePreferences.getFCMToken(this);
if (token != null && !token.isEmpty()) { if (token != null && !token.isEmpty()) {
LokiPushNotificationManager.unregister(token, this); LokiPushNotificationManager.unregister(token, this);

View File

@@ -6,8 +6,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.database.Cursor import android.database.Cursor
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
@@ -31,14 +29,9 @@ import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.ConversationActivity import org.thoughtcrime.securesms.conversation.ConversationActivity
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.groups.GroupManager
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet import org.thoughtcrime.securesms.loki.dialogs.*
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.protocol.ClosedGroupsProtocol import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation
import org.thoughtcrime.securesms.loki.utilities.* 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.protocol.shelved.syncmessages.SyncMessagesProtocol
import org.whispersystems.signalservice.loki.utilities.toHexString import org.whispersystems.signalservice.loki.utilities.toHexString
import java.io.IOException import java.io.IOException
import java.util.*
class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate { class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate {
private lateinit var glide: GlideRequests private lateinit var glide: GlideRequests
@@ -178,7 +172,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
// Clear all data if this is a secondary device // Clear all data if this is a secondary device
if (TextSecurePreferences.getMasterHexEncodedPublicKey(this) != null) { if (TextSecurePreferences.getMasterHexEncodedPublicKey(this) != null) {
TextSecurePreferences.setWasUnlinked(this, true) TextSecurePreferences.setWasUnlinked(this, true)
ApplicationContext.getInstance(this).clearData() ApplicationContext.getInstance(this).clearAllData()
} }
} }
@@ -191,36 +185,15 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
if (hasViewedSeed || !isMasterDevice) { if (hasViewedSeed || !isMasterDevice) {
seedReminderView.visibility = View.GONE seedReminderView.visibility = View.GONE
} }
// Show key pair migration sheet if needed
// Multi device removal sheet if (KeyPairUtilities.hasV2KeyPair(this)) { return }
if (!TextSecurePreferences.getHasSeenMultiDeviceRemovalSheet(this)) { val lastNudge = TextSecurePreferences.getLastKeyPairMigrationNudge(this)
TextSecurePreferences.setHasSeenMultiDeviceRemovalSheet(this) val nudgeInterval: Long = 3 * 24 * 60 * 60 * 1000 // 3 days
val userPublicKey = TextSecurePreferences.getLocalNumber(this) val nudge = (Date().time - lastNudge > nudgeInterval)
val deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userPublicKey) if (!nudge) { return }
if (deviceLinks.isNotEmpty()) { val keyPairMigrationSheet = KeyPairMigrationBottomSheet()
val bottomSheet = MultiDeviceRemovalBottomSheet() keyPairMigrationSheet.show(supportFragmentManager, keyPairMigrationSheet.tag)
bottomSheet.onOKTapped = { TextSecurePreferences.setLastKeyPairMigrationNudge(this, Date().time)
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
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@@ -27,13 +27,13 @@ class ClearAllDataDialog : DialogFragment() {
private fun clearAllData() { private fun clearAllData() {
if (KeyPairUtilities.hasV2KeyPair(requireContext())) { if (KeyPairUtilities.hasV2KeyPair(requireContext())) {
ApplicationContext.getInstance(context).clearData() ApplicationContext.getInstance(context).clearAllData()
} else { } else {
val dialog = AlertDialog.Builder(requireContext()) val dialog = AlertDialog.Builder(requireContext())
val message = "Weve upgraded the way Session IDs are generated, so you will be unable to restore your current Session ID." val message = "Weve upgraded the way Session IDs are generated, so you will be unable to restore your current Session ID."
dialog.setMessage(message) dialog.setMessage(message)
dialog.setPositiveButton("Yes") { _, _ -> dialog.setPositiveButton("Yes") { _, _ ->
ApplicationContext.getInstance(context).clearData() ApplicationContext.getInstance(context).clearAllData()
} }
dialog.setNegativeButton("Cancel") { _, _ -> dialog.setNegativeButton("Cancel") { _, _ ->
// Do nothing // Do nothing

View File

@@ -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<FrameLayout>(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("Youre 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()
}
}

View File

@@ -197,7 +197,7 @@ object MultiDeviceProtocol {
FileServerAPI.shared.removeDeviceLink(slaveDeviceLink) // Attempt to clean up on the file server FileServerAPI.shared.removeDeviceLink(slaveDeviceLink) // Attempt to clean up on the file server
} }
TextSecurePreferences.setWasUnlinked(context, true) TextSecurePreferences.setWasUnlinked(context, true)
ApplicationContext.getInstance(context).clearData() ApplicationContext.getInstance(context).clearAllData()
} }
} }
} }

View File

@@ -1342,5 +1342,13 @@ public class TextSecurePreferences {
public static void setLastSnodePoolRefreshDate(Context context, Date date) { public static void setLastSnodePoolRefreshDate(Context context, Date date) {
setLongPreference(context, "last_snode_pool_refresh_date", date.getTime()); 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 // endregion
} }