From f1ea035197d92aff93d37c22561a3812719ae244 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Wed, 1 Apr 2020 19:55:18 -0400 Subject: [PATCH] Re-enable and clean up Signal PINs. - Require PINs during registration agian. - Change min length to 4. - Allow the full-screen megaphone to be enabled remotely. - Clean up and remove some code. --- .../securesms/keyvalue/KbsValues.java | 25 +------ .../securesms/keyvalue/PinValues.java | 19 +++++- .../keyvalue/RegistrationValues.java | 3 +- .../lock/RegistrationLockDialog.java | 6 +- .../lock/SignalPinReminderDialog.java | 6 +- .../lock/v2/ConfirmKbsPinRepository.java | 2 +- .../securesms/lock/v2/KbsConstants.java | 7 +- .../securesms/lock/v2/PinUtil.java | 4 -- .../securesms/megaphone/Megaphones.java | 40 +++-------- .../megaphone/PinsForAllSchedule.java | 49 +++++-------- .../profiles/edit/EditProfileFragment.java | 4 -- .../RegistrationCompleteFragment.java | 8 +-- .../fragments/RegistrationLockFragment.java | 2 +- .../securesms/util/FeatureFlags.java | 11 ++- app/src/main/res/values/strings.xml | 1 - .../megaphone/PinsForAllScheduleTest.java | 68 ------------------- 16 files changed, 68 insertions(+), 187 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java index 28f9dc87c9..0cc7a09432 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/KbsValues.java @@ -1,10 +1,8 @@ package org.thoughtcrime.securesms.keyvalue; -import androidx.annotation.CheckResult; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.thoughtcrime.securesms.lock.v2.PinKeyboardType; import org.thoughtcrime.securesms.util.JsonUtils; import org.whispersystems.signalservice.api.RegistrationLockData; import org.whispersystems.signalservice.api.kbs.MasterKey; @@ -19,7 +17,6 @@ public final class KbsValues { private static final String MASTER_KEY = "kbs.registration_lock_master_key"; private static final String TOKEN_RESPONSE = "kbs.token_response"; private static final String LOCK_LOCAL_PIN_HASH = "kbs.registration_lock_local_pin_hash"; - private static final String KEYBOARD_TYPE = "kbs.keyboard_type"; private final KeyValueStore store; @@ -35,7 +32,6 @@ public final class KbsValues { .remove(V2_LOCK_ENABLED) .remove(TOKEN_RESPONSE) .remove(LOCK_LOCAL_PIN_HASH) - .remove(KEYBOARD_TYPE) .commit(); } @@ -97,15 +93,15 @@ public final class KbsValues { } } - public @Nullable String getLocalPinHash() { + public synchronized @Nullable String getLocalPinHash() { return store.getString(LOCK_LOCAL_PIN_HASH, null); } - public boolean isV2RegistrationLockEnabled() { + public synchronized boolean isV2RegistrationLockEnabled() { return store.getBoolean(V2_LOCK_ENABLED, false); } - public @Nullable TokenResponse getRegistrationLockTokenResponse() { + public synchronized @Nullable TokenResponse getRegistrationLockTokenResponse() { String token = store.getString(TOKEN_RESPONSE, null); if (token == null) return null; @@ -116,19 +112,4 @@ public final class KbsValues { throw new AssertionError(e); } } - - public void setKeyboardType(@NonNull PinKeyboardType keyboardType) { - store.beginWrite() - .putString(KEYBOARD_TYPE, keyboardType.getCode()) - .commit(); - } - - @CheckResult - public @NonNull PinKeyboardType getKeyboardType() { - return PinKeyboardType.fromCode(store.getString(KEYBOARD_TYPE, null)); - } - - public boolean hasMigratedToPinsForAll() { - return store.getString(KEYBOARD_TYPE, null) != null && store.getBoolean(V2_LOCK_ENABLED, false); - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java index dfa6729879..adb3237dca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/PinValues.java @@ -1,16 +1,24 @@ package org.thoughtcrime.securesms.keyvalue; +import androidx.annotation.CheckResult; +import androidx.annotation.NonNull; + import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.lock.SignalPinReminders; +import org.thoughtcrime.securesms.lock.v2.PinKeyboardType; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.util.TextSecurePreferences; +/** + * Specifically handles just the UI/UX state around PINs. For actual keys, see {@link KbsValues}. + */ public final class PinValues { private static final String TAG = Log.tag(PinValues.class); private static final String LAST_SUCCESSFUL_ENTRY = "pin.last_successful_entry"; private static final String NEXT_INTERVAL = "pin.interval_index"; + private static final String KEYBOARD_TYPE = "kbs.keyboard_type"; private final KeyValueStore store; @@ -47,7 +55,6 @@ public final class PinValues { .apply(); } - public void onPinChange() { long nextInterval = SignalPinReminders.INITIAL_INTERVAL; Log.i(TAG, "onPinChange() nextInterval: " + nextInterval); @@ -65,4 +72,14 @@ public final class PinValues { public long getLastSuccessfulEntryTime() { return store.getLong(LAST_SUCCESSFUL_ENTRY, TextSecurePreferences.getRegistrationLockLastReminderTime(ApplicationDependencies.getApplication())); } + + public void setKeyboardType(@NonNull PinKeyboardType keyboardType) { + store.beginWrite() + .putString(KEYBOARD_TYPE, keyboardType.getCode()) + .commit(); + } + + public @NonNull PinKeyboardType getKeyboardType() { + return PinKeyboardType.fromCode(store.getString(KEYBOARD_TYPE, null)); + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java index 78656b7dfd..72db1774f6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/RegistrationValues.java @@ -17,8 +17,7 @@ public final class RegistrationValues { public synchronized void onFirstEverAppLaunch() { store.beginWrite() .putBoolean(REGISTRATION_COMPLETE, false) - // TODO [greyson] [pins] Maybe re-enable in the future -// .putBoolean(PIN_REQUIRED, true) + .putBoolean(PIN_REQUIRED, true) .commit(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java index 4c9eeb7985..0ab69f8c52 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java @@ -154,7 +154,7 @@ public final class RegistrationLockDialog { if (s == null) return; String pin = s.toString(); if (TextUtils.isEmpty(pin)) return; - if (pin.length() < KbsConstants.LEGACY_MINIMUM_PIN_LENGTH) return; + if (pin.length() < KbsConstants.MINIMUM_PIN_LENGTH) return; if (PinHashing.verifyLocalPinHash(localPinHash, pin)) { dialog.dismiss(); @@ -186,9 +186,9 @@ public final class RegistrationLockDialog { String pinValue = pin.getText().toString().replace(" ", ""); String repeatValue = repeat.getText().toString().replace(" ", ""); - if (pinValue.length() < KbsConstants.LEGACY_MINIMUM_PIN_LENGTH) { + if (pinValue.length() < KbsConstants.MINIMUM_PIN_LENGTH) { Toast.makeText(context, - context.getString(R.string.RegistrationLockDialog_the_registration_lock_pin_must_be_at_least_d_digits, KbsConstants.LEGACY_MINIMUM_PIN_LENGTH), + context.getString(R.string.RegistrationLockDialog_the_registration_lock_pin_must_be_at_least_d_digits, KbsConstants.MINIMUM_PIN_LENGTH), Toast.LENGTH_LONG).show(); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java b/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java index a1f3e82801..4216125f4f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/SignalPinReminderDialog.java @@ -73,7 +73,7 @@ public final class SignalPinReminderDialog { } }); - switch (SignalStore.kbsValues().getKeyboardType()) { + switch (SignalStore.pinValues().getKeyboardType()) { case NUMERIC: pinEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD); break; @@ -115,7 +115,7 @@ public final class SignalPinReminderDialog { pinEditText.addTextChangedListener(new SimpleTextWatcher() { @Override public void onTextChanged(String text) { - if (text.length() >= KbsConstants.minimumPossiblePinLength()) { + if (text.length() >= KbsConstants.MINIMUM_PIN_LENGTH) { submit.setEnabled(true); } else { submit.setEnabled(false); @@ -192,7 +192,7 @@ public final class SignalPinReminderDialog { if (pin == null) return; if (TextUtils.isEmpty(pin)) return; - if (pin.length() < KbsConstants.minimumPossiblePinLength()) return; + if (pin.length() < KbsConstants.MINIMUM_PIN_LENGTH) return; if (PinHashing.verifyLocalPinHash(localPinHash, pin)) { callback.onPinCorrect(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/ConfirmKbsPinRepository.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/ConfirmKbsPinRepository.java index 433231bd1b..ff83e7c51a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/ConfirmKbsPinRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/ConfirmKbsPinRepository.java @@ -48,7 +48,7 @@ final class ConfirmKbsPinRepository { TextSecurePreferences.clearOldRegistrationLockPin(context); TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis()); TextSecurePreferences.setRegistrationLockNextReminderInterval(context, RegistrationLockReminders.INITIAL_INTERVAL); - SignalStore.kbsValues().setKeyboardType(keyboard); + SignalStore.pinValues().setKeyboardType(keyboard); ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL); Log.i(TAG, "Pin set on KBS"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/KbsConstants.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/KbsConstants.java index 4453603b6d..2876700dbf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/KbsConstants.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/KbsConstants.java @@ -2,12 +2,7 @@ package org.thoughtcrime.securesms.lock.v2; public final class KbsConstants { - public static final int MINIMUM_PIN_LENGTH = 6; - public static final int LEGACY_MINIMUM_PIN_LENGTH = 4; + public static final int MINIMUM_PIN_LENGTH = 4; private KbsConstants() { } - - public static int minimumPossiblePinLength() { - return LEGACY_MINIMUM_PIN_LENGTH; - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/PinUtil.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/PinUtil.java index cd9ee8b3e5..bb03c06cf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/PinUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/PinUtil.java @@ -16,8 +16,4 @@ public final class PinUtil { public static boolean userHasPin(@NonNull Context context) { return TextSecurePreferences.isV1RegistrationLockEnabled(context) || SignalStore.kbsValues().isV2RegistrationLockEnabled(); } - - public static boolean shouldShowPinCreationDuringRegistration(@NonNull Context context) { - return FeatureFlags.pinsForAll() && !PinUtil.userHasPin(context); - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java index 08d1f0c762..82f641ddc9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java @@ -136,40 +136,20 @@ public final class Megaphones { }) .build(); } else { - Megaphone.Builder builder = new Megaphone.Builder(Event.PINS_FOR_ALL, Megaphone.Style.BASIC) - .setMandatory(true) - .setImage(R.drawable.kbs_pin_megaphone); + return new Megaphone.Builder(Event.PINS_FOR_ALL, Megaphone.Style.BASIC) + .setMandatory(true) + .setImage(R.drawable.kbs_pin_megaphone) + .setTitle(R.string.KbsMegaphone__create_a_pin) + .setBody(R.string.KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account) + .setActionButton(R.string.KbsMegaphone__create_pin, (megaphone, listener) -> { + Intent intent = CreateKbsPinActivity.getIntentForPinCreate(ApplicationDependencies.getApplication()); - if (PinUtil.userHasPin(ApplicationDependencies.getApplication())) { - return buildPinsForAllMegaphoneForUserWithPin(builder.enableSnooze(null)); - } else { - return buildPinsForAllMegaphoneForUserWithoutPin(builder.enableSnooze(null)); - } + listener.onMegaphoneNavigationRequested(intent, CreateKbsPinActivity.REQUEST_NEW_PIN); + }) + .build(); } } - private static @NonNull Megaphone buildPinsForAllMegaphoneForUserWithPin(@NonNull Megaphone.Builder builder) { - return builder.setTitle(R.string.KbsMegaphone__introducing_pins) - .setBody(R.string.KbsMegaphone__your_registration_lock_is_now_called_a_pin) - .setActionButton(R.string.KbsMegaphone__update_pin, (megaphone, listener) -> { - Intent intent = CreateKbsPinActivity.getIntentForPinChangeFromSettings(ApplicationDependencies.getApplication()); - - listener.onMegaphoneNavigationRequested(intent, CreateKbsPinActivity.REQUEST_NEW_PIN); - }) - .build(); - } - - private static @NonNull Megaphone buildPinsForAllMegaphoneForUserWithoutPin(@NonNull Megaphone.Builder builder) { - return builder.setTitle(R.string.KbsMegaphone__create_a_pin) - .setBody(R.string.KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account) - .setActionButton(R.string.KbsMegaphone__create_pin, (megaphone, listener) -> { - Intent intent = CreateKbsPinActivity.getIntentForPinCreate(ApplicationDependencies.getApplication()); - - listener.onMegaphoneNavigationRequested(intent, CreateKbsPinActivity.REQUEST_NEW_PIN); - }) - .build(); - } - private static @NonNull Megaphone buildPinReminderMegaphone(@NonNull Context context) { return new Megaphone.Builder(Event.PIN_REMINDER, Megaphone.Style.BASIC) .setTitle(R.string.Megaphones_verify_your_signal_pin) diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java index aa0bb08b5e..5067fd22c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java @@ -1,16 +1,11 @@ package org.thoughtcrime.securesms.megaphone; -import android.content.Context; - import androidx.annotation.VisibleForTesting; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; -import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; -import org.thoughtcrime.securesms.util.CensorshipUtil; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.Util; import java.util.concurrent.TimeUnit; @@ -19,36 +14,25 @@ class PinsForAllSchedule implements MegaphoneSchedule { @VisibleForTesting static final long DAYS_UNTIL_FULLSCREEN = 8L; - @VisibleForTesting - static final long DAYS_REMAINING_MAX = DAYS_UNTIL_FULLSCREEN - 1; - private final MegaphoneSchedule schedule = new RecurringSchedule(TimeUnit.DAYS.toMillis(2)); static boolean shouldDisplayFullScreen(long firstVisible, long currentTime) { - return false; - // TODO [greyson] [pins] Maybe re-enable if we ever do a blocking flow again -// if (pinCreationFailedDuringRegistration()) { -// return true; -// } -// -// if (firstVisible == 0L) { -// return false; -// } else { -// return currentTime - firstVisible >= TimeUnit.DAYS.toMillis(DAYS_UNTIL_FULLSCREEN); -// } - } - - static long getDaysRemaining(long firstVisible, long currentTime) { - if (firstVisible == 0L) { - return DAYS_REMAINING_MAX; - } else { - return Util.clamp(DAYS_REMAINING_MAX - TimeUnit.MILLISECONDS.toDays(currentTime - firstVisible), 0, DAYS_REMAINING_MAX); + if (!FeatureFlags.pinsForAllMandatory()) { + return false; } + + if (firstVisible == 0L) { + return false; + } + + return currentTime - firstVisible >= TimeUnit.DAYS.toMillis(DAYS_UNTIL_FULLSCREEN); } @Override public boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime) { - if (!isEnabled()) return false; + if (!isEnabled()) { + return false; + } if (shouldDisplayFullScreen(firstVisible, currentTime)) { return true; @@ -58,6 +42,10 @@ class PinsForAllSchedule implements MegaphoneSchedule { } private static boolean isEnabled() { + if (SignalStore.kbsValues().isV2RegistrationLockEnabled()) { + return false; + } + if (FeatureFlags.pinsForAllMegaphoneKillSwitch()) { return false; } @@ -74,10 +62,6 @@ class PinsForAllSchedule implements MegaphoneSchedule { return false; } - if (SignalStore.kbsValues().hasMigratedToPinsForAll()) { - return false; - } - return FeatureFlags.pinsForAll(); } @@ -87,8 +71,7 @@ class PinsForAllSchedule implements MegaphoneSchedule { !TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication()); } - private static final boolean newlyRegisteredV1PinUser() { + private static boolean newlyRegisteredV1PinUser() { return SignalStore.registrationValues().pinWasRequiredAtRegistration() && TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication()); } - } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java index a51e15a248..49db8daea0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/edit/EditProfileFragment.java @@ -307,10 +307,6 @@ public class EditProfileFragment extends Fragment { private void handleUpload() { viewModel.submitProfile(uploadResult -> { if (uploadResult == EditProfileRepository.UploadResult.SUCCESS) { - if (!PinUtil.shouldShowPinCreationDuringRegistration(requireContext())) { - SignalStore.registrationValues().setRegistrationComplete(); - } - ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PROFILE_NAMES_FOR_ALL); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) handleFinishedLollipop(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragment.java index e56c4f45fa..fb0dbdbf77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragment.java @@ -41,12 +41,8 @@ public final class RegistrationCompleteFragment extends BaseRegistrationFragment profile.putExtra(EditProfileActivity.SHOW_TOOLBAR, false); - if (PinUtil.shouldShowPinCreationDuringRegistration(requireContext())) { - Intent kbs = CreateKbsPinActivity.getIntentForPinCreate(requireContext()); - activity.startActivity(chainIntents(chainIntents(profile, kbs), main)); - } else { - activity.startActivity(chainIntents(profile, main)); - } + Intent kbs = CreateKbsPinActivity.getIntentForPinCreate(requireContext()); + activity.startActivity(chainIntents(chainIntents(profile, kbs), main)); } activity.finish(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java index 90c04f68d7..1f11047fcf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragment.java @@ -303,7 +303,7 @@ public final class RegistrationLockFragment extends BaseRegistrationFragment { } private void handleSuccessfulPinEntry() { - SignalStore.kbsValues().setKeyboardType(getPinEntryKeyboardType()); + SignalStore.pinValues().setKeyboardType(getPinEntryKeyboardType()); if (FeatureFlags.storageServiceRestore()) { long startTime = System.currentTimeMillis(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index 377c3553b4..5c5b4194e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -50,6 +50,7 @@ public final class FeatureFlags { private static final String MESSAGE_REQUESTS = "android.messageRequests"; private static final String USERNAMES = "android.usernames"; private static final String PINS_FOR_ALL = "android.pinsForAll"; + private static final String PINS_FOR_ALL_MANDATORY = "android.pinsForAllMandatory"; private static final String PINS_MEGAPHONE_KILL_SWITCH = "android.pinsMegaphoneKillSwitch"; private static final String PROFILE_NAMES_MEGAPHONE = "android.profileNamesMegaphone"; private static final String STORAGE_SERVICE = "android.storageService.2"; @@ -61,6 +62,7 @@ public final class FeatureFlags { private static final Set REMOTE_CAPABLE = Sets.newHashSet( PINS_FOR_ALL, + PINS_FOR_ALL_MANDATORY, PINS_MEGAPHONE_KILL_SWITCH, PROFILE_NAMES_MEGAPHONE, MESSAGE_REQUESTS, @@ -178,13 +180,18 @@ public final class FeatureFlags { return value; } - /** Enables new KBS UI and notices but does not require user to set a pin */ + /** Starts showing prompts for users to create PINs. */ public static boolean pinsForAll() { return SignalStore.registrationValues().pinWasRequiredAtRegistration() || - SignalStore.kbsValues().hasMigratedToPinsForAll() || + pinsForAllMandatory() || getValue(PINS_FOR_ALL, false); } + /** Makes it so the user will eventually see a fullscreen splash requiring them to create a PIN. */ + public static boolean pinsForAllMandatory() { + return getValue(PINS_FOR_ALL_MANDATORY, false); + } + /** Safety flag to disable Pins for All Megaphone */ public static boolean pinsForAllMegaphoneKillSwitch() { return getValue(PINS_MEGAPHONE_KILL_SWITCH, false); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 52430b8bda..8799c79baf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1865,7 +1865,6 @@ PINs add another layer of security to your Signal account. Create PIN Introducing PINs - Your Registration Lock is now called a PIN. Updating it takes seconds. Update PIN We\'ll remind you later. Creating a PIN will become mandatory in %1$d days. We\'ll remind you later. Confirming your PIN will become mandatory in %1$d days. diff --git a/app/src/test/java/org/thoughtcrime/securesms/megaphone/PinsForAllScheduleTest.java b/app/src/test/java/org/thoughtcrime/securesms/megaphone/PinsForAllScheduleTest.java index 90eb87335e..f37631b40e 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/megaphone/PinsForAllScheduleTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/megaphone/PinsForAllScheduleTest.java @@ -98,74 +98,6 @@ public class PinsForAllScheduleTest { assertTrue(result); } - @Test - public void givenFirstVisibleIsZero_whenIGetDaysRemaining_thenIExpectMax() { - // GIVEN - long firstVisible = 0; - long expected = PinsForAllSchedule.DAYS_REMAINING_MAX; - - // WHEN - long result = PinsForAllSchedule.getDaysRemaining(firstVisible, 0); - - // THEN - assertEquals(expected, result); - } - - @Test - public void givenFirstVisibleIsNow_whenIGetDaysRemaining_thenIExpectMax() { - // GIVEN - long now = System.currentTimeMillis(); - long expected = PinsForAllSchedule.DAYS_REMAINING_MAX; - - // WHEN - long result = PinsForAllSchedule.getDaysRemaining(now, now); - - // THEN - assertEquals(expected, result); - } - - @Test - public void givenFirstVisibleIsFiveSecondsAgo_whenIGetDaysRemaining_thenIExpectMax() { - // GIVEN - long now = System.currentTimeMillis(); - long firstVisible = now - TimeUnit.SECONDS.toMillis(5); - long expected = PinsForAllSchedule.DAYS_REMAINING_MAX; - - // WHEN - long result = PinsForAllSchedule.getDaysRemaining(firstVisible, now); - - // THEN - assertEquals(expected, result); - } - - @Test - public void givenFirstVisibleIsADayAgo_whenIGetDaysRemaining_thenIExpectMaxLessOne() { - // GIVEN - long now = System.currentTimeMillis(); - long firstVisible = now - TimeUnit.DAYS.toMillis(1); - long expected = PinsForAllSchedule.DAYS_REMAINING_MAX - 1; - - // WHEN - long result = PinsForAllSchedule.getDaysRemaining(firstVisible, now); - - // THEN - assertEquals(expected, result); - } - - @Test - public void givenFirstVisibleIsAMonthAgo_whenIGetDaysRemaining_thenIExpectZero() { - // GIVEN - long now = System.currentTimeMillis(); - long firstVisible = now - TimeUnit.DAYS.toMillis(31); - long expected = 0; - - // WHEN - long result = PinsForAllSchedule.getDaysRemaining(firstVisible, now); - - // THEN - assertEquals(expected, result); - } - @Test public void whenUserIsANewInstallAndFlagIsDisabled_whenIShouldDisplay_thenIExpectFalse() { // GIVEN