Keep old device inactive after a successful transfer.

This commit is contained in:
Cody Henthorne
2021-03-16 16:50:10 -04:00
committed by Greyson Parrelli
parent 31e3e37c9b
commit 45178b3eb3
20 changed files with 302 additions and 43 deletions

View File

@@ -9,6 +9,8 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.devicetransfer.olddevice.OldDeviceTransferLockedDialog;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.AppStartup;
import org.thoughtcrime.securesms.util.CachedInflater;
import org.thoughtcrime.securesms.util.CommunicationActions;
@@ -70,6 +72,9 @@ public class MainActivity extends PassphraseRequiredActivity {
protected void onResume() {
super.onResume();
dynamicTheme.onResume(this);
if (SignalStore.misc().isOldDeviceTransferLocked()) {
OldDeviceTransferLockedDialog.show(getSupportFragmentManager());
}
}
@Override

View File

@@ -49,6 +49,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
private static final int STATE_CREATE_PROFILE_NAME = 6;
private static final int STATE_CREATE_SIGNAL_PIN = 7;
private static final int STATE_TRANSFER_ONGOING = 8;
private static final int STATE_TRANSFER_LOCKED = 9;
private SignalServiceNetworkAccess networkAccess;
private BroadcastReceiver clearKeyReceiver;
@@ -151,6 +152,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
case STATE_CREATE_SIGNAL_PIN: return getCreateSignalPinIntent();
case STATE_CREATE_PROFILE_NAME: return getCreateProfileNameIntent();
case STATE_TRANSFER_ONGOING: return getOldDeviceTransferIntent();
case STATE_TRANSFER_LOCKED: return getOldDeviceTransferLockedIntent();
default: return null;
}
}
@@ -172,6 +174,8 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
return STATE_CREATE_SIGNAL_PIN;
} else if (EventBus.getDefault().getStickyEvent(TransferStatus.class) != null && getClass() != OldDeviceTransferActivity.class) {
return STATE_TRANSFER_ONGOING;
} else if (SignalStore.misc().isOldDeviceTransferLocked()) {
return STATE_TRANSFER_LOCKED;
} else {
return STATE_NORMAL;
}
@@ -232,6 +236,13 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
return intent;
}
private @Nullable Intent getOldDeviceTransferLockedIntent() {
if (getClass() == MainActivity.class) {
return null;
}
return MainActivity.clearTop(this);
}
private Intent getRoutedIntent(Class<?> destination, @Nullable Intent nextIntent) {
final Intent intent = new Intent(this, destination);
if (nextIntent != null) intent.putExtra("next_intent", nextIntent);

View File

@@ -15,6 +15,7 @@ import org.signal.devicetransfer.DeviceToDeviceTransferService;
import org.signal.devicetransfer.TransferStatus;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.devicetransfer.DeviceTransferFragment;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
/**
* Shows transfer progress on the old device. Most logic is in {@link DeviceTransferFragment}
@@ -54,6 +55,7 @@ public final class OldDeviceTransferFragment extends DeviceTransferFragment {
ignoreTransferStatusEvents();
EventBus.getDefault().removeStickyEvent(TransferStatus.class);
DeviceToDeviceTransferService.stop(requireContext());
SignalStore.misc().markOldDeviceTransferLocked();
NavHostFragment.findNavController(OldDeviceTransferFragment.this).navigate(R.id.action_oldDeviceTransfer_to_oldDeviceTransferComplete);
} else {
status.setText(getString(R.string.DeviceTransfer__d_messages_so_far, event.getMessageCount()));

View File

@@ -0,0 +1,60 @@
package org.thoughtcrime.securesms.devicetransfer.olddevice;
import android.app.Dialog;
import android.os.Bundle;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.net.DeviceTransferBlockingInterceptor;
/**
* Blocking dialog shown on old devices after a successful transfer to prevent use unless
* the user takes action to reactivate.
*/
public final class OldDeviceTransferLockedDialog extends DialogFragment {
private static final String TAG = Log.tag(OldDeviceTransferLockedDialog.class);
private static final String FRAGMENT_TAG = "OldDeviceTransferLockedDialog";
public static void show(@NonNull FragmentManager fragmentManager) {
if (fragmentManager.findFragmentByTag(FRAGMENT_TAG) != null) {
Log.i(TAG, "Locked dialog already being shown");
return;
}
new OldDeviceTransferLockedDialog().show(fragmentManager, FRAGMENT_TAG);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCancelable(false);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(requireContext(), R.style.Signal_ThemeOverlay_Dialog_Rounded);
dialogBuilder.setView(R.layout.old_device_transfer_locked_dialog_fragment)
.setPositiveButton(R.string.OldDeviceTransferLockedDialog__done, (d, w) -> OldDeviceExitActivity.exit(requireActivity()))
.setNegativeButton(R.string.OldDeviceTransferLockedDialog__cancel_and_activate_this_device, (d, w) -> onUnlockRequest());
Dialog dialog = dialogBuilder.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
private void onUnlockRequest() {
SignalStore.misc().clearOldDeviceTransferLocked();
DeviceTransferBlockingInterceptor.getInstance().unblockNetwork();
}
}

View File

@@ -92,7 +92,7 @@ public final class OldDeviceTransferSetupFragment extends DeviceTransferSetupFra
switch (step) {
case SETTING_UP:
case WAITING:
return R.string.OldDeviceTransferSetup__searching_for_your_new_android_device;
return R.string.OldDeviceTransferSetup__searching_for_new_android_device;
case ERROR:
return R.string.OldDeviceTransferSetup__an_unexpected_error_occurred_while_attempting_to_connect_to_your_old_device;
case TROUBLESHOOTING:

View File

@@ -4,12 +4,13 @@ import androidx.annotation.NonNull;
public final class MiscellaneousValues extends SignalStoreValues {
private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time";
private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time";
private static final String LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time";
private static final String LAST_GV1_ROUTINE_MIGRATION_TIME = "misc.last_gv1_routine_migration_time";
private static final String USERNAME_SHOW_REMINDER = "username.show.reminder";
private static final String CLIENT_DEPRECATED = "misc.client_deprecated";
private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time";
private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time";
private static final String LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time";
private static final String LAST_GV1_ROUTINE_MIGRATION_TIME = "misc.last_gv1_routine_migration_time";
private static final String USERNAME_SHOW_REMINDER = "username.show.reminder";
private static final String CLIENT_DEPRECATED = "misc.client_deprecated";
private static final String OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked";
MiscellaneousValues(@NonNull KeyValueStore store) {
super(store);
@@ -67,4 +68,16 @@ public final class MiscellaneousValues extends SignalStoreValues {
public void clearClientDeprecated() {
putBoolean(CLIENT_DEPRECATED, false);
}
public boolean isOldDeviceTransferLocked() {
return getBoolean(OLD_DEVICE_TRANSFER_LOCKED, false);
}
public void markOldDeviceTransferLocked() {
putBoolean(OLD_DEVICE_TRANSFER_LOCKED, true);
}
public void clearOldDeviceTransferLocked() {
putBoolean(OLD_DEVICE_TRANSFER_LOCKED, false);
}
}

View File

@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import java.io.IOException;
@@ -21,12 +22,16 @@ public final class DeviceTransferBlockingInterceptor implements Interceptor {
private static final DeviceTransferBlockingInterceptor INSTANCE = new DeviceTransferBlockingInterceptor();
private volatile boolean blockNetworking = false;
private volatile boolean blockNetworking;
public static DeviceTransferBlockingInterceptor getInstance() {
return INSTANCE;
}
public DeviceTransferBlockingInterceptor() {
this.blockNetworking = SignalStore.misc().isOldDeviceTransferLocked();
}
@Override
public @NonNull Response intercept(@NonNull Chain chain) throws IOException {
if (!blockNetworking) {