From 490944a02a254c731721f0bc2840ab211452e9cf Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Tue, 16 Mar 2021 10:18:02 -0400 Subject: [PATCH] Improve UI/UX around device transfer. --- .../securesms/backup/FullBackupExporter.java | 7 + .../securesms/backup/FullBackupImporter.java | 10 +- .../DeviceTransferSetupFragment.java | 7 +- .../DeviceTransferSetupViewModel.java | 3 +- .../securesms/devicetransfer/SetupStep.java | 2 +- .../NewDeviceTransferSetupFragment.java | 2 - .../newdevice/TransferOrRestoreFragment.java | 4 +- .../olddevice/OldDeviceExitActivity.java | 20 +- .../OldDeviceTransferCompleteFragment.java | 2 +- .../OldDeviceTransferSetupFragment.java | 2 - .../securesms/util/TextSecurePreferences.java | 71 +++++++ app/src/main/proto/Backups.proto | 9 +- .../layout/device_transfer_setup_fragment.xml | 72 ++------ .../device_transfer_setup_verify_layout.xml | 67 +++++++ ..._setup_waiting_for_other_verify_layout.xml | 46 +++++ .../res/layout/fragment_transfer_restore.xml | 4 +- .../old_device_transfer_complete_fragment.xml | 11 +- ..._device_transfer_instructions_fragment.xml | 174 ++++++++++-------- app/src/main/res/values/strings.xml | 11 +- .../devicetransfer/DeviceTransferClient.java | 1 + .../devicetransfer/DeviceTransferServer.java | 1 + .../devicetransfer/NetworkClientThread.java | 14 +- .../devicetransfer/NetworkServerThread.java | 15 +- .../signal/devicetransfer/TransferStatus.java | 7 +- 24 files changed, 394 insertions(+), 168 deletions(-) create mode 100644 app/src/main/res/layout/device_transfer_setup_verify_layout.xml create mode 100644 app/src/main/res/layout/device_transfer_setup_waiting_for_other_verify_layout.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java index 4b819c1be..fa5eabefe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.java @@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.profiles.AvatarHelper; import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.Stopwatch; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.kdf.HKDFv3; import org.whispersystems.libsignal.util.ByteUtil; @@ -154,6 +155,12 @@ public class FullBackupExporter extends FullBackupBase { EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count)); outputStream.write(preference); } + + for (BackupProtos.SharedPreference preference : TextSecurePreferences.getPreferencesToSaveToBackup(context)) { + throwIfCanceled(cancellationSignal); + EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count)); + outputStream.write(preference); + } stopwatch.split("prefs"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java index 494472f8f..070089f7c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java @@ -45,6 +45,7 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Objects; @@ -213,7 +214,14 @@ public class FullBackupImporter extends FullBackupBase { @SuppressLint("ApplySharedPref") private static void processPreference(@NonNull Context context, SharedPreference preference) { SharedPreferences preferences = context.getSharedPreferences(preference.getFile(), 0); - preferences.edit().putString(preference.getKey(), preference.getValue()).commit(); + + if (preference.hasValue()) { + preferences.edit().putString(preference.getKey(), preference.getValue()).commit(); + } else if (preference.hasBooleanValue()) { + preferences.edit().putBoolean(preference.getKey(), preference.getBooleanValue()).commit(); + } else if (preference.hasIsStringSetValue() && preference.getIsStringSetValue()) { + preferences.edit().putStringSet(preference.getKey(), new HashSet<>(preference.getStringSetValueList())).commit(); + } } private static void dropAllTables(@NonNull SQLiteDatabase db) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupFragment.java index 375d55f85..e1504ed28 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupFragment.java @@ -73,7 +73,8 @@ public abstract class DeviceTransferSetupFragment extends LoggingFragment { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { Group progressGroup = view.findViewById(R.id.device_transfer_setup_fragment_progress_group); Group errorGroup = view.findViewById(R.id.device_transfer_setup_fragment_error_group); - Group verifyGroup = view.findViewById(R.id.device_transfer_setup_fragment_verify_group); + View verifyGroup = view.findViewById(R.id.device_transfer_setup_fragment_verify); + View waitingGroup = view.findViewById(R.id.device_transfer_setup_fragment_waiting); View troubleshooting = view.findViewById(R.id.device_transfer_setup_fragment_troubleshooting); TextView status = view.findViewById(R.id.device_transfer_setup_fragment_status); TextView error = view.findViewById(R.id.device_transfer_setup_fragment_error); @@ -90,6 +91,7 @@ public abstract class DeviceTransferSetupFragment extends LoggingFragment { progressGroup.setVisibility(step.isProgress() ? View.VISIBLE : View.GONE); errorGroup.setVisibility(step.isError() ? View.VISIBLE : View.GONE); verifyGroup.setVisibility(step == SetupStep.VERIFY ? View.VISIBLE : View.GONE); + waitingGroup.setVisibility(step == SetupStep.WAITING_FOR_OTHER_TO_VERIFY ? View.VISIBLE : View.GONE); troubleshooting.setVisibility(step == SetupStep.TROUBLESHOOTING ? View.VISIBLE : View.GONE); Log.i(TAG, "Handling step: " + step.name()); @@ -166,8 +168,7 @@ public abstract class DeviceTransferSetupFragment extends LoggingFragment { viewModel.onVerified(); }); break; - case CONNECTING: - status.setText(getStatusTextForStep(step, false)); + case WAITING_FOR_OTHER_TO_VERIFY: break; case CONNECTED: Log.d(TAG, "Connected! isNotShutdown: " + viewModel.isNotShutdown()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupViewModel.java index 6f12ae1a6..e240b539b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/DeviceTransferSetupViewModel.java @@ -59,6 +59,7 @@ public final class DeviceTransferSetupViewModel extends ViewModel { case SERVICE_CONNECTED: store.update(s -> s.updateStep(SetupStep.CONNECTED)); break; + case SHUTDOWN: case FAILED: store.update(s -> s.updateStep(SetupStep.ERROR)); break; @@ -116,7 +117,7 @@ public final class DeviceTransferSetupViewModel extends ViewModel { } public void onVerified() { - store.update(s -> s.updateStep(SetupStep.CONNECTING)); + store.update(s -> s.updateStep(SetupStep.WAITING_FOR_OTHER_TO_VERIFY)); } public void onResume() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/SetupStep.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/SetupStep.java index 09dc274ef..7c76c17b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/SetupStep.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/SetupStep.java @@ -18,7 +18,7 @@ public enum SetupStep { SETTING_UP(true, false), WAITING(true, false), VERIFY(false, false), - CONNECTING(true, false), + WAITING_FOR_OTHER_TO_VERIFY(false, false), CONNECTED(true, false), TROUBLESHOOTING(false, false), ERROR(false, true); diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java index 519efc911..1296f13e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragment.java @@ -67,8 +67,6 @@ public final class NewDeviceTransferSetupFragment extends DeviceTransferSetupFra : R.string.NewDeviceTransferSetup__preparing_to_connect_to_old_android_device; case WAITING: return R.string.NewDeviceTransferSetup__waiting_for_old_device_to_connect; - case CONNECTING: - return R.string.NewDeviceTransferSetup__connecting_to_old_android_device; case ERROR: return R.string.NewDeviceTransferSetup__an_unexpected_error_occurred_while_attempting_to_connect_to_your_old_device; case TROUBLESHOOTING: diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java index 13e1ade30..f5c5620a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragment.java @@ -29,8 +29,8 @@ public final class TransferOrRestoreFragment extends LoggingFragment { view.findViewById(R.id.transfer_or_restore_fragment_restore) .setOnClickListener(v -> Navigation.findNavController(v).navigate(R.id.action_choose_backup)); - String description = getString(R.string.TransferOrRestoreFragment__transfer_your_account_and_message_history_from_your_old_android_device); - String toBold = getString(R.string.TransferOrRestoreFragment__you_must_have_access_to_your_old_device); + String description = getString(R.string.TransferOrRestoreFragment__transfer_your_account_and_messages_from_your_old_android_device); + String toBold = getString(R.string.TransferOrRestoreFragment__you_need_access_to_your_old_device); TextView transferDescriptionView = view.findViewById(R.id.transfer_or_restore_fragment_transfer_description); transferDescriptionView.setText(SpanUtil.boldSubstring(description, toBold)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceExitActivity.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceExitActivity.java index 67e825b0b..78ade870e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceExitActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceExitActivity.java @@ -1,9 +1,12 @@ package org.thoughtcrime.securesms.devicetransfer.olddevice; +import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.os.Build; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; public class OldDeviceExitActivity extends AppCompatActivity { @@ -11,14 +14,23 @@ public class OldDeviceExitActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - finish(); + finishAll(this); } - public static void exit(Context context) { - Intent intent = new Intent(context, OldDeviceExitActivity.class); + public static void exit(@NonNull Activity activity) { + Intent intent = new Intent(activity, OldDeviceExitActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - context.startActivity(intent); + activity.startActivity(intent); + finishAll(activity); + } + + private static void finishAll(@NonNull Activity activity) { + if (Build.VERSION.SDK_INT < 21) { + activity.finishAffinity(); + } else { + activity.finishAndRemoveTask(); + } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferCompleteFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferCompleteFragment.java index 42b61ce76..60a4301a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferCompleteFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferCompleteFragment.java @@ -36,6 +36,6 @@ public final class OldDeviceTransferCompleteFragment extends LoggingFragment { } private void close() { - OldDeviceExitActivity.exit(requireContext()); + OldDeviceExitActivity.exit(requireActivity()); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java index 277e5191e..eaf2fd3fe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/olddevice/OldDeviceTransferSetupFragment.java @@ -93,8 +93,6 @@ public final class OldDeviceTransferSetupFragment extends DeviceTransferSetupFra case SETTING_UP: case WAITING: return R.string.OldDeviceTransferSetup__searching_for_your_new_android_device; - case CONNECTING: - return R.string.OldDeviceTransferSetup__connecting_to_new_android_device; case ERROR: return R.string.OldDeviceTransferSetup__an_unexpected_error_occurred_while_attempting_to_connect_to_your_old_device; case TROUBLESHOOTING: diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 70e3e24d8..386bf833b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -16,6 +16,7 @@ import androidx.core.app.NotificationCompat; import org.greenrobot.eventbus.EventBus; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.backup.BackupProtos; import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver; import org.thoughtcrime.securesms.keyvalue.SettingsValues; import org.thoughtcrime.securesms.lock.RegistrationLockReminders; @@ -25,9 +26,11 @@ import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.IOException; import java.security.SecureRandom; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -209,6 +212,74 @@ public class TextSecurePreferences { private static final String ARGON2_TESTED = "argon2_tested"; + private static final String[] booleanPreferencesToBackup = {SCREEN_SECURITY_PREF, + INCOGNITO_KEYBORAD_PREF, + ALWAYS_RELAY_CALLS_PREF, + READ_RECEIPTS_PREF, + TYPING_INDICATORS, + SHOW_UNIDENTIFIED_DELIVERY_INDICATORS, + UNIVERSAL_UNIDENTIFIED_ACCESS, + NOTIFICATION_PREF, + VIBRATE_PREF, + IN_THREAD_NOTIFICATION_PREF, + CALL_NOTIFICATIONS_PREF, + CALL_VIBRATE_PREF, + NEW_CONTACTS_NOTIFICATIONS, + SHOW_INVITE_REMINDER_PREF, + SYSTEM_EMOJI_PREF, + ENTER_SENDS_PREF}; + + private static final String[] stringPreferencesToBackup = {LED_COLOR_PREF, + LED_BLINK_PREF, + REPEAT_ALERTS_PREF, + NOTIFICATION_PRIVACY_PREF, + THEME_PREF, + LANGUAGE_PREF, + MESSAGE_BODY_TEXT_SIZE_PREF}; + + private static final String[] stringSetPreferencesToBackup = {MEDIA_DOWNLOAD_MOBILE_PREF, + MEDIA_DOWNLOAD_WIFI_PREF, + MEDIA_DOWNLOAD_ROAMING_PREF}; + + public static List getPreferencesToSaveToBackup(@NonNull Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + List backupProtos = new ArrayList<>(); + String defaultFile = context.getPackageName() + "_preferences"; + + for (String booleanPreference : booleanPreferencesToBackup) { + if (preferences.contains(booleanPreference)) { + backupProtos.add(BackupProtos.SharedPreference.newBuilder() + .setFile(defaultFile) + .setKey(booleanPreference) + .setBooleanValue(preferences.getBoolean(booleanPreference, false)) + .build()); + } + } + + for (String stringPreference : stringPreferencesToBackup) { + if (preferences.contains(stringPreference)) { + backupProtos.add(BackupProtos.SharedPreference.newBuilder() + .setFile(defaultFile) + .setKey(stringPreference) + .setValue(preferences.getString(stringPreference, null)) + .build()); + } + } + + for (String stringSetPreference : stringSetPreferencesToBackup) { + if (preferences.contains(stringSetPreference)) { + backupProtos.add(BackupProtos.SharedPreference.newBuilder() + .setFile(defaultFile) + .setKey(stringSetPreference) + .setIsStringSetValue(true) + .addAllStringSetValue(preferences.getStringSet(stringSetPreference, Collections.emptySet())) + .build()); + } + } + + return backupProtos; + } + public static boolean isScreenLockEnabled(@NonNull Context context) { return getBooleanPreference(context, SCREEN_LOCK, false); } diff --git a/app/src/main/proto/Backups.proto b/app/src/main/proto/Backups.proto index 925ea2677..3b44d5d1f 100644 --- a/app/src/main/proto/Backups.proto +++ b/app/src/main/proto/Backups.proto @@ -25,9 +25,12 @@ message SqlStatement { } message SharedPreference { - optional string file = 1; - optional string key = 2; - optional string value = 3; + optional string file = 1; + optional string key = 2; + optional string value = 3; + optional bool booleanValue = 4; + repeated string stringSetValue = 5; + optional bool isStringSetValue = 6; } message Attachment { diff --git a/app/src/main/res/layout/device_transfer_setup_fragment.xml b/app/src/main/res/layout/device_transfer_setup_fragment.xml index 2f59813f5..fc8e446fb 100644 --- a/app/src/main/res/layout/device_transfer_setup_fragment.xml +++ b/app/src/main/res/layout/device_transfer_setup_fragment.xml @@ -65,67 +65,32 @@ - + - + - - - - - - + app:layout_constraintTop_toTopOf="parent" /> - - @@ -145,6 +109,7 @@ android:id="@+id/device_transfer_setup_fragment_progress_group" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:visibility="gone" app:constraint_referenced_ids="device_transfer_setup_fragment_progress,device_transfer_setup_fragment_status" /> - - diff --git a/app/src/main/res/layout/device_transfer_setup_verify_layout.xml b/app/src/main/res/layout/device_transfer_setup_verify_layout.xml new file mode 100644 index 000000000..85da00d33 --- /dev/null +++ b/app/src/main/res/layout/device_transfer_setup_verify_layout.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/device_transfer_setup_waiting_for_other_verify_layout.xml b/app/src/main/res/layout/device_transfer_setup_waiting_for_other_verify_layout.xml new file mode 100644 index 000000000..190762d42 --- /dev/null +++ b/app/src/main/res/layout/device_transfer_setup_waiting_for_other_verify_layout.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_transfer_restore.xml b/app/src/main/res/layout/fragment_transfer_restore.xml index f5a944c9d..606d88d8a 100644 --- a/app/src/main/res/layout/fragment_transfer_restore.xml +++ b/app/src/main/res/layout/fragment_transfer_restore.xml @@ -72,7 +72,7 @@ app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toStartOf="@+id/transfer_or_restore_fragment_transfer_header" app:layout_constraintTop_toBottomOf="@+id/transfer_or_restore_fragment_transfer_header" - tools:text="@string/TransferOrRestoreFragment__transfer_your_account_and_message_history_from_your_old_android_device" /> + tools:text="@string/TransferOrRestoreFragment__transfer_your_account_and_messages_from_your_old_android_device" /> @@ -112,7 +112,7 @@ android:id="@+id/transfer_or_restore_fragment_restore_description" android:layout_width="0dp" android:layout_height="wrap_content" - android:text="@string/TransferOrRestoreFragment__restore_your_messages_and_media_from_a_local_backup" + android:text="@string/TransferOrRestoreFragment__restore_your_messages_from_a_local_backup" android:textColor="@color/signal_text_secondary" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/old_device_transfer_complete_fragment.xml b/app/src/main/res/layout/old_device_transfer_complete_fragment.xml index 042ca0840..28c104b90 100644 --- a/app/src/main/res/layout/old_device_transfer_complete_fragment.xml +++ b/app/src/main/res/layout/old_device_transfer_complete_fragment.xml @@ -21,14 +21,19 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - diff --git a/app/src/main/res/layout/old_device_transfer_instructions_fragment.xml b/app/src/main/res/layout/old_device_transfer_instructions_fragment.xml index 4f31145ae..7f84309de 100644 --- a/app/src/main/res/layout/old_device_transfer_instructions_fragment.xml +++ b/app/src/main/res/layout/old_device_transfer_instructions_fragment.xml @@ -1,10 +1,10 @@ + android:orientation="vertical"> - - - + android:layout_height="match_parent" + android:clipToPadding="false" + android:fillViewport="true" + android:scrollIndicators="bottom" + tools:ignore="UnusedAttribute"> - - - + android:orientation="vertical" + android:paddingBottom="16dp"> - + - + - + - + - + - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb925a6de..e4d2dac1a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2760,10 +2760,10 @@ Transfer or restore account If you have previously registered a Signal account, you can transfer or restore your account and messages Transfer from Android device - Transfer your account and message history from your old Android device. You must have access to your old device. - You must have access to your old device. + Transfer your account and messages from your old Android device. You need access to your old device. + You need access to your old device. Restore from backup - Restore your messages and media from a local backup. If you don\'t restore now, you wouldn\'t be able to restore later. + Restore your messages from a local backup. If you don’t restore now, you won\'t be able to restore later. Open Signal on your old Android phone @@ -2779,7 +2779,6 @@ Preparing to connect to old Android device… Taking a moment, should be ready soon Waiting for old Android device to connect… - Connecting to old Android device… Signal needs the location permission to discover and connect to your old Android device. Signal needs location services enabled to discover and connect with your old Android device. Signal needs Wi-Fi on to discover and connect with your old Android device. Wi-Fi needs to be on but it does not have to be connected to a Wi-Fi network. @@ -2789,7 +2788,6 @@ Searching for your new Android device… - Connecting to new Android device… Signal needs the location permission to discover and connect to your new Android device. Signal needs location services enabled to discover and connect with your new Android device. Signal needs Wi-Fi on to discover and connect with your new Android device. Wi-Fi needs to be on but it does not have to be connected to a Wi-Fi network. @@ -2825,6 +2823,9 @@ Make sure both devices are in transfer mode. Go to support page Try again + Waiting for other device + Tap Continue on your other device to start the transfer. + Tap Continue on your other device… Cannot transfer from a newer versions of Signal diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferClient.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferClient.java index 1ee105e75..5d9079a63 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferClient.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferClient.java @@ -181,6 +181,7 @@ final class DeviceTransferClient implements Handler.Callback { update(TransferStatus.networkConnected()); break; case NetworkClientThread.NETWORK_CLIENT_STOPPED: + update(TransferStatus.shutdown()); internalShutdown(); break; default: diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferServer.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferServer.java index 33c0f8c67..82d561e6b 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferServer.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/DeviceTransferServer.java @@ -146,6 +146,7 @@ final class DeviceTransferServer implements Handler.Callback { startWifiDirect(message.arg1); break; case NetworkServerThread.NETWORK_SERVER_STOPPED: + update(TransferStatus.shutdown()); internalShutdown(); break; case NetworkServerThread.NETWORK_CLIENT_CONNECTED: diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkClientThread.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkClientThread.java index 5868a54ab..e3e703684 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkClientThread.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkClientThread.java @@ -92,8 +92,18 @@ final class NetworkClientThread extends Thread { Log.i(TAG, "Waiting for user to verify sas"); awaitAuthenticationCodeVerification(); Log.d(TAG, "Waiting for server to tell us they also verified"); - //noinspection ResultOfMethodCallIgnored - inputStream.read(); + outputStream.write(0x43); + outputStream.flush(); + try { + int result = inputStream.read(); + if (result == -1) { + Log.w(TAG, "Something happened waiting for server to verify"); + throw new DeviceTransferAuthentication.DeviceTransferAuthenticationException("server disconnected while we waited"); + } + } catch (IOException e) { + Log.w(TAG, "Something happened waiting for server to verify", e); + throw new DeviceTransferAuthentication.DeviceTransferAuthenticationException(e); + } handler.sendEmptyMessage(NETWORK_CLIENT_CONNECTED); clientTask.run(context, outputStream); diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkServerThread.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkServerThread.java index 7eb74f297..63362a7d7 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkServerThread.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/NetworkServerThread.java @@ -73,10 +73,21 @@ final class NetworkServerThread extends Thread { Log.i(TAG, "Waiting for user to verify sas"); awaitAuthenticationCodeVerification(); - - handler.sendEmptyMessage(NETWORK_CLIENT_CONNECTED); + Log.d(TAG, "Waiting for client to tell us they also verified"); outputStream.write(0x43); outputStream.flush(); + try { + int result = inputStream.read(); + if (result == -1) { + Log.w(TAG, "Something happened waiting for client to verify"); + throw new DeviceTransferAuthentication.DeviceTransferAuthenticationException("client disconnected while we waited"); + } + } catch (IOException e) { + Log.w(TAG, "Something happened waiting for client to verify", e); + throw new DeviceTransferAuthentication.DeviceTransferAuthenticationException(e); + } + + handler.sendEmptyMessage(NETWORK_CLIENT_CONNECTED); serverTask.run(context, inputStream); outputStream.write(0x53); diff --git a/device-transfer/lib/src/main/java/org/signal/devicetransfer/TransferStatus.java b/device-transfer/lib/src/main/java/org/signal/devicetransfer/TransferStatus.java index 581c4b23c..6a14ba0b2 100644 --- a/device-transfer/lib/src/main/java/org/signal/devicetransfer/TransferStatus.java +++ b/device-transfer/lib/src/main/java/org/signal/devicetransfer/TransferStatus.java @@ -59,6 +59,10 @@ public class TransferStatus { return new TransferStatus(TransferMode.UNAVAILABLE); } + public static @NonNull TransferStatus shutdown() { + return new TransferStatus(TransferMode.SHUTDOWN); + } + public static @NonNull TransferStatus failed() { return new TransferStatus(TransferMode.FAILED); } @@ -72,6 +76,7 @@ public class TransferStatus { NETWORK_CONNECTED, VERIFICATION_REQUIRED, SERVICE_CONNECTED, - SERVICE_DISCONNECTED + SERVICE_DISCONNECTED, + SHUTDOWN } }