mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 15:58:34 +00:00
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.
This commit is contained in:
parent
6f961ade74
commit
f1ea035197
@ -1,10 +1,8 @@
|
|||||||
package org.thoughtcrime.securesms.keyvalue;
|
package org.thoughtcrime.securesms.keyvalue;
|
||||||
|
|
||||||
import androidx.annotation.CheckResult;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.lock.v2.PinKeyboardType;
|
|
||||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||||
import org.whispersystems.signalservice.api.RegistrationLockData;
|
import org.whispersystems.signalservice.api.RegistrationLockData;
|
||||||
import org.whispersystems.signalservice.api.kbs.MasterKey;
|
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 MASTER_KEY = "kbs.registration_lock_master_key";
|
||||||
private static final String TOKEN_RESPONSE = "kbs.token_response";
|
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 LOCK_LOCAL_PIN_HASH = "kbs.registration_lock_local_pin_hash";
|
||||||
private static final String KEYBOARD_TYPE = "kbs.keyboard_type";
|
|
||||||
|
|
||||||
private final KeyValueStore store;
|
private final KeyValueStore store;
|
||||||
|
|
||||||
@ -35,7 +32,6 @@ public final class KbsValues {
|
|||||||
.remove(V2_LOCK_ENABLED)
|
.remove(V2_LOCK_ENABLED)
|
||||||
.remove(TOKEN_RESPONSE)
|
.remove(TOKEN_RESPONSE)
|
||||||
.remove(LOCK_LOCAL_PIN_HASH)
|
.remove(LOCK_LOCAL_PIN_HASH)
|
||||||
.remove(KEYBOARD_TYPE)
|
|
||||||
.commit();
|
.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);
|
return store.getString(LOCK_LOCAL_PIN_HASH, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isV2RegistrationLockEnabled() {
|
public synchronized boolean isV2RegistrationLockEnabled() {
|
||||||
return store.getBoolean(V2_LOCK_ENABLED, false);
|
return store.getBoolean(V2_LOCK_ENABLED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable TokenResponse getRegistrationLockTokenResponse() {
|
public synchronized @Nullable TokenResponse getRegistrationLockTokenResponse() {
|
||||||
String token = store.getString(TOKEN_RESPONSE, null);
|
String token = store.getString(TOKEN_RESPONSE, null);
|
||||||
|
|
||||||
if (token == null) return null;
|
if (token == null) return null;
|
||||||
@ -116,19 +112,4 @@ public final class KbsValues {
|
|||||||
throw new AssertionError(e);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
package org.thoughtcrime.securesms.keyvalue;
|
package org.thoughtcrime.securesms.keyvalue;
|
||||||
|
|
||||||
|
import androidx.annotation.CheckResult;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.lock.SignalPinReminders;
|
import org.thoughtcrime.securesms.lock.SignalPinReminders;
|
||||||
|
import org.thoughtcrime.securesms.lock.v2.PinKeyboardType;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
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 {
|
public final class PinValues {
|
||||||
|
|
||||||
private static final String TAG = Log.tag(PinValues.class);
|
private static final String TAG = Log.tag(PinValues.class);
|
||||||
|
|
||||||
private static final String LAST_SUCCESSFUL_ENTRY = "pin.last_successful_entry";
|
private static final String LAST_SUCCESSFUL_ENTRY = "pin.last_successful_entry";
|
||||||
private static final String NEXT_INTERVAL = "pin.interval_index";
|
private static final String NEXT_INTERVAL = "pin.interval_index";
|
||||||
|
private static final String KEYBOARD_TYPE = "kbs.keyboard_type";
|
||||||
|
|
||||||
private final KeyValueStore store;
|
private final KeyValueStore store;
|
||||||
|
|
||||||
@ -47,7 +55,6 @@ public final class PinValues {
|
|||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onPinChange() {
|
public void onPinChange() {
|
||||||
long nextInterval = SignalPinReminders.INITIAL_INTERVAL;
|
long nextInterval = SignalPinReminders.INITIAL_INTERVAL;
|
||||||
Log.i(TAG, "onPinChange() nextInterval: " + nextInterval);
|
Log.i(TAG, "onPinChange() nextInterval: " + nextInterval);
|
||||||
@ -65,4 +72,14 @@ public final class PinValues {
|
|||||||
public long getLastSuccessfulEntryTime() {
|
public long getLastSuccessfulEntryTime() {
|
||||||
return store.getLong(LAST_SUCCESSFUL_ENTRY, TextSecurePreferences.getRegistrationLockLastReminderTime(ApplicationDependencies.getApplication()));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ public final class RegistrationValues {
|
|||||||
public synchronized void onFirstEverAppLaunch() {
|
public synchronized void onFirstEverAppLaunch() {
|
||||||
store.beginWrite()
|
store.beginWrite()
|
||||||
.putBoolean(REGISTRATION_COMPLETE, false)
|
.putBoolean(REGISTRATION_COMPLETE, false)
|
||||||
// TODO [greyson] [pins] Maybe re-enable in the future
|
.putBoolean(PIN_REQUIRED, true)
|
||||||
// .putBoolean(PIN_REQUIRED, true)
|
|
||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ public final class RegistrationLockDialog {
|
|||||||
if (s == null) return;
|
if (s == null) return;
|
||||||
String pin = s.toString();
|
String pin = s.toString();
|
||||||
if (TextUtils.isEmpty(pin)) return;
|
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)) {
|
if (PinHashing.verifyLocalPinHash(localPinHash, pin)) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
@ -186,9 +186,9 @@ public final class RegistrationLockDialog {
|
|||||||
String pinValue = pin.getText().toString().replace(" ", "");
|
String pinValue = pin.getText().toString().replace(" ", "");
|
||||||
String repeatValue = repeat.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,
|
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();
|
Toast.LENGTH_LONG).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public final class SignalPinReminderDialog {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
switch (SignalStore.kbsValues().getKeyboardType()) {
|
switch (SignalStore.pinValues().getKeyboardType()) {
|
||||||
case NUMERIC:
|
case NUMERIC:
|
||||||
pinEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
|
pinEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
|
||||||
break;
|
break;
|
||||||
@ -115,7 +115,7 @@ public final class SignalPinReminderDialog {
|
|||||||
pinEditText.addTextChangedListener(new SimpleTextWatcher() {
|
pinEditText.addTextChangedListener(new SimpleTextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(String text) {
|
public void onTextChanged(String text) {
|
||||||
if (text.length() >= KbsConstants.minimumPossiblePinLength()) {
|
if (text.length() >= KbsConstants.MINIMUM_PIN_LENGTH) {
|
||||||
submit.setEnabled(true);
|
submit.setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
submit.setEnabled(false);
|
submit.setEnabled(false);
|
||||||
@ -192,7 +192,7 @@ public final class SignalPinReminderDialog {
|
|||||||
if (pin == null) return;
|
if (pin == null) return;
|
||||||
if (TextUtils.isEmpty(pin)) 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)) {
|
if (PinHashing.verifyLocalPinHash(localPinHash, pin)) {
|
||||||
callback.onPinCorrect();
|
callback.onPinCorrect();
|
||||||
|
@ -48,7 +48,7 @@ final class ConfirmKbsPinRepository {
|
|||||||
TextSecurePreferences.clearOldRegistrationLockPin(context);
|
TextSecurePreferences.clearOldRegistrationLockPin(context);
|
||||||
TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis());
|
TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis());
|
||||||
TextSecurePreferences.setRegistrationLockNextReminderInterval(context, RegistrationLockReminders.INITIAL_INTERVAL);
|
TextSecurePreferences.setRegistrationLockNextReminderInterval(context, RegistrationLockReminders.INITIAL_INTERVAL);
|
||||||
SignalStore.kbsValues().setKeyboardType(keyboard);
|
SignalStore.pinValues().setKeyboardType(keyboard);
|
||||||
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL);
|
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL);
|
||||||
|
|
||||||
Log.i(TAG, "Pin set on KBS");
|
Log.i(TAG, "Pin set on KBS");
|
||||||
|
@ -2,12 +2,7 @@ package org.thoughtcrime.securesms.lock.v2;
|
|||||||
|
|
||||||
public final class KbsConstants {
|
public final class KbsConstants {
|
||||||
|
|
||||||
public static final int MINIMUM_PIN_LENGTH = 6;
|
public static final int MINIMUM_PIN_LENGTH = 4;
|
||||||
public static final int LEGACY_MINIMUM_PIN_LENGTH = 4;
|
|
||||||
|
|
||||||
private KbsConstants() { }
|
private KbsConstants() { }
|
||||||
|
|
||||||
public static int minimumPossiblePinLength() {
|
|
||||||
return LEGACY_MINIMUM_PIN_LENGTH;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,4 @@ public final class PinUtil {
|
|||||||
public static boolean userHasPin(@NonNull Context context) {
|
public static boolean userHasPin(@NonNull Context context) {
|
||||||
return TextSecurePreferences.isV1RegistrationLockEnabled(context) || SignalStore.kbsValues().isV2RegistrationLockEnabled();
|
return TextSecurePreferences.isV1RegistrationLockEnabled(context) || SignalStore.kbsValues().isV2RegistrationLockEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldShowPinCreationDuringRegistration(@NonNull Context context) {
|
|
||||||
return FeatureFlags.pinsForAll() && !PinUtil.userHasPin(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -136,31 +136,10 @@ public final class Megaphones {
|
|||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
} else {
|
} else {
|
||||||
Megaphone.Builder builder = new Megaphone.Builder(Event.PINS_FOR_ALL, Megaphone.Style.BASIC)
|
return new Megaphone.Builder(Event.PINS_FOR_ALL, Megaphone.Style.BASIC)
|
||||||
.setMandatory(true)
|
.setMandatory(true)
|
||||||
.setImage(R.drawable.kbs_pin_megaphone);
|
.setImage(R.drawable.kbs_pin_megaphone)
|
||||||
|
.setTitle(R.string.KbsMegaphone__create_a_pin)
|
||||||
if (PinUtil.userHasPin(ApplicationDependencies.getApplication())) {
|
|
||||||
return buildPinsForAllMegaphoneForUserWithPin(builder.enableSnooze(null));
|
|
||||||
} else {
|
|
||||||
return buildPinsForAllMegaphoneForUserWithoutPin(builder.enableSnooze(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
.setBody(R.string.KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account)
|
||||||
.setActionButton(R.string.KbsMegaphone__create_pin, (megaphone, listener) -> {
|
.setActionButton(R.string.KbsMegaphone__create_pin, (megaphone, listener) -> {
|
||||||
Intent intent = CreateKbsPinActivity.getIntentForPinCreate(ApplicationDependencies.getApplication());
|
Intent intent = CreateKbsPinActivity.getIntentForPinCreate(ApplicationDependencies.getApplication());
|
||||||
@ -169,6 +148,7 @@ public final class Megaphones {
|
|||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static @NonNull Megaphone buildPinReminderMegaphone(@NonNull Context context) {
|
private static @NonNull Megaphone buildPinReminderMegaphone(@NonNull Context context) {
|
||||||
return new Megaphone.Builder(Event.PIN_REMINDER, Megaphone.Style.BASIC)
|
return new Megaphone.Builder(Event.PIN_REMINDER, Megaphone.Style.BASIC)
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
package org.thoughtcrime.securesms.megaphone;
|
package org.thoughtcrime.securesms.megaphone;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
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.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -19,36 +14,25 @@ class PinsForAllSchedule implements MegaphoneSchedule {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final long DAYS_UNTIL_FULLSCREEN = 8L;
|
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));
|
private final MegaphoneSchedule schedule = new RecurringSchedule(TimeUnit.DAYS.toMillis(2));
|
||||||
|
|
||||||
static boolean shouldDisplayFullScreen(long firstVisible, long currentTime) {
|
static boolean shouldDisplayFullScreen(long firstVisible, long currentTime) {
|
||||||
|
if (!FeatureFlags.pinsForAllMandatory()) {
|
||||||
return false;
|
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) {
|
if (firstVisible == 0L) {
|
||||||
return DAYS_REMAINING_MAX;
|
return false;
|
||||||
} else {
|
|
||||||
return Util.clamp(DAYS_REMAINING_MAX - TimeUnit.MILLISECONDS.toDays(currentTime - firstVisible), 0, DAYS_REMAINING_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return currentTime - firstVisible >= TimeUnit.DAYS.toMillis(DAYS_UNTIL_FULLSCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime) {
|
public boolean shouldDisplay(int seenCount, long lastSeen, long firstVisible, long currentTime) {
|
||||||
if (!isEnabled()) return false;
|
if (!isEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldDisplayFullScreen(firstVisible, currentTime)) {
|
if (shouldDisplayFullScreen(firstVisible, currentTime)) {
|
||||||
return true;
|
return true;
|
||||||
@ -58,6 +42,10 @@ class PinsForAllSchedule implements MegaphoneSchedule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEnabled() {
|
private static boolean isEnabled() {
|
||||||
|
if (SignalStore.kbsValues().isV2RegistrationLockEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (FeatureFlags.pinsForAllMegaphoneKillSwitch()) {
|
if (FeatureFlags.pinsForAllMegaphoneKillSwitch()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -74,10 +62,6 @@ class PinsForAllSchedule implements MegaphoneSchedule {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SignalStore.kbsValues().hasMigratedToPinsForAll()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FeatureFlags.pinsForAll();
|
return FeatureFlags.pinsForAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +71,7 @@ class PinsForAllSchedule implements MegaphoneSchedule {
|
|||||||
!TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication());
|
!TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean newlyRegisteredV1PinUser() {
|
private static boolean newlyRegisteredV1PinUser() {
|
||||||
return SignalStore.registrationValues().pinWasRequiredAtRegistration() && TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication());
|
return SignalStore.registrationValues().pinWasRequiredAtRegistration() && TextSecurePreferences.isV1RegistrationLockEnabled(ApplicationDependencies.getApplication());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -307,10 +307,6 @@ public class EditProfileFragment extends Fragment {
|
|||||||
private void handleUpload() {
|
private void handleUpload() {
|
||||||
viewModel.submitProfile(uploadResult -> {
|
viewModel.submitProfile(uploadResult -> {
|
||||||
if (uploadResult == EditProfileRepository.UploadResult.SUCCESS) {
|
if (uploadResult == EditProfileRepository.UploadResult.SUCCESS) {
|
||||||
if (!PinUtil.shouldShowPinCreationDuringRegistration(requireContext())) {
|
|
||||||
SignalStore.registrationValues().setRegistrationComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PROFILE_NAMES_FOR_ALL);
|
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PROFILE_NAMES_FOR_ALL);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) handleFinishedLollipop();
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) handleFinishedLollipop();
|
||||||
|
@ -41,12 +41,8 @@ public final class RegistrationCompleteFragment extends BaseRegistrationFragment
|
|||||||
|
|
||||||
profile.putExtra(EditProfileActivity.SHOW_TOOLBAR, false);
|
profile.putExtra(EditProfileActivity.SHOW_TOOLBAR, false);
|
||||||
|
|
||||||
if (PinUtil.shouldShowPinCreationDuringRegistration(requireContext())) {
|
|
||||||
Intent kbs = CreateKbsPinActivity.getIntentForPinCreate(requireContext());
|
Intent kbs = CreateKbsPinActivity.getIntentForPinCreate(requireContext());
|
||||||
activity.startActivity(chainIntents(chainIntents(profile, kbs), main));
|
activity.startActivity(chainIntents(chainIntents(profile, kbs), main));
|
||||||
} else {
|
|
||||||
activity.startActivity(chainIntents(profile, main));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activity.finish();
|
activity.finish();
|
||||||
|
@ -303,7 +303,7 @@ public final class RegistrationLockFragment extends BaseRegistrationFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleSuccessfulPinEntry() {
|
private void handleSuccessfulPinEntry() {
|
||||||
SignalStore.kbsValues().setKeyboardType(getPinEntryKeyboardType());
|
SignalStore.pinValues().setKeyboardType(getPinEntryKeyboardType());
|
||||||
|
|
||||||
if (FeatureFlags.storageServiceRestore()) {
|
if (FeatureFlags.storageServiceRestore()) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
@ -50,6 +50,7 @@ public final class FeatureFlags {
|
|||||||
private static final String MESSAGE_REQUESTS = "android.messageRequests";
|
private static final String MESSAGE_REQUESTS = "android.messageRequests";
|
||||||
private static final String USERNAMES = "android.usernames";
|
private static final String USERNAMES = "android.usernames";
|
||||||
private static final String PINS_FOR_ALL = "android.pinsForAll";
|
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 PINS_MEGAPHONE_KILL_SWITCH = "android.pinsMegaphoneKillSwitch";
|
||||||
private static final String PROFILE_NAMES_MEGAPHONE = "android.profileNamesMegaphone";
|
private static final String PROFILE_NAMES_MEGAPHONE = "android.profileNamesMegaphone";
|
||||||
private static final String STORAGE_SERVICE = "android.storageService.2";
|
private static final String STORAGE_SERVICE = "android.storageService.2";
|
||||||
@ -61,6 +62,7 @@ public final class FeatureFlags {
|
|||||||
|
|
||||||
private static final Set<String> REMOTE_CAPABLE = Sets.newHashSet(
|
private static final Set<String> REMOTE_CAPABLE = Sets.newHashSet(
|
||||||
PINS_FOR_ALL,
|
PINS_FOR_ALL,
|
||||||
|
PINS_FOR_ALL_MANDATORY,
|
||||||
PINS_MEGAPHONE_KILL_SWITCH,
|
PINS_MEGAPHONE_KILL_SWITCH,
|
||||||
PROFILE_NAMES_MEGAPHONE,
|
PROFILE_NAMES_MEGAPHONE,
|
||||||
MESSAGE_REQUESTS,
|
MESSAGE_REQUESTS,
|
||||||
@ -178,13 +180,18 @@ public final class FeatureFlags {
|
|||||||
return value;
|
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() {
|
public static boolean pinsForAll() {
|
||||||
return SignalStore.registrationValues().pinWasRequiredAtRegistration() ||
|
return SignalStore.registrationValues().pinWasRequiredAtRegistration() ||
|
||||||
SignalStore.kbsValues().hasMigratedToPinsForAll() ||
|
pinsForAllMandatory() ||
|
||||||
getValue(PINS_FOR_ALL, false);
|
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 */
|
/** Safety flag to disable Pins for All Megaphone */
|
||||||
public static boolean pinsForAllMegaphoneKillSwitch() {
|
public static boolean pinsForAllMegaphoneKillSwitch() {
|
||||||
return getValue(PINS_MEGAPHONE_KILL_SWITCH, false);
|
return getValue(PINS_MEGAPHONE_KILL_SWITCH, false);
|
||||||
|
@ -1865,7 +1865,6 @@
|
|||||||
<string name="KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account">PINs add another layer of security to your Signal account.</string>
|
<string name="KbsMegaphone__pins_add_another_layer_of_security_to_your_signal_account">PINs add another layer of security to your Signal account.</string>
|
||||||
<string name="KbsMegaphone__create_pin">Create PIN</string>
|
<string name="KbsMegaphone__create_pin">Create PIN</string>
|
||||||
<string name="KbsMegaphone__introducing_pins">Introducing PINs</string>
|
<string name="KbsMegaphone__introducing_pins">Introducing PINs</string>
|
||||||
<string name="KbsMegaphone__your_registration_lock_is_now_called_a_pin">Your Registration Lock is now called a PIN. Updating it takes seconds.</string>
|
|
||||||
<string name="KbsMegaphone__update_pin">Update PIN</string>
|
<string name="KbsMegaphone__update_pin">Update PIN</string>
|
||||||
<string name="KbsMegaphone__well_remind_you_later_creating_a_pin">We\'ll remind you later. Creating a PIN will become mandatory in %1$d days.</string>
|
<string name="KbsMegaphone__well_remind_you_later_creating_a_pin">We\'ll remind you later. Creating a PIN will become mandatory in %1$d days.</string>
|
||||||
<string name="KbsMegaphone__well_remind_you_later_confirming_your_pin">We\'ll remind you later. Confirming your PIN will become mandatory in %1$d days.</string>
|
<string name="KbsMegaphone__well_remind_you_later_confirming_your_pin">We\'ll remind you later. Confirming your PIN will become mandatory in %1$d days.</string>
|
||||||
|
@ -98,74 +98,6 @@ public class PinsForAllScheduleTest {
|
|||||||
assertTrue(result);
|
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
|
@Test
|
||||||
public void whenUserIsANewInstallAndFlagIsDisabled_whenIShouldDisplay_thenIExpectFalse() {
|
public void whenUserIsANewInstallAndFlagIsDisabled_whenIShouldDisplay_thenIExpectFalse() {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
|
Loading…
x
Reference in New Issue
Block a user