Skip to content

Commit

Permalink
Implement new PIN UX.
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-signal committed Feb 1, 2020
1 parent 109d679 commit fb82420
Show file tree
Hide file tree
Showing 71 changed files with 2,989 additions and 192 deletions.
18 changes: 14 additions & 4 deletions app/src/main/AndroidManifest.xml
Expand Up @@ -414,11 +414,21 @@
android:windowSoftInputMode="stateVisible"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>

<activity android:name=".lock.v2.CreateKbsPinActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="adjustResize"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>

<activity android:name=".lock.v2.KbsMigrationActivity"
android:theme="@style/TextSecure.LightRegistrationTheme"
android:windowSoftInputMode="adjustResize"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>

<activity android:name=".ClearProfileAvatarActivity"
android:theme="@style/Theme.AppCompat.Dialog.Alert"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:icon="@drawable/clear_profile_avatar"
android:label="@string/AndroidManifest_remove_photo">
android:theme="@style/Theme.AppCompat.Dialog.Alert"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:icon="@drawable/clear_profile_avatar"
android:label="@string/AndroidManifest_remove_photo">

<intent-filter>
<action android:name="org.thoughtcrime.securesms.action.CLEAR_PROFILE_PHOTO"/>
Expand Down
Expand Up @@ -49,6 +49,7 @@
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
import org.thoughtcrime.securesms.logging.AndroidLogger;
import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger;
Expand Down Expand Up @@ -250,6 +251,7 @@ private void initializeFirstEverAppLaunch() {
TextSecurePreferences.setLastExperienceVersionCode(this, Util.getCanonicalVersionCode());
TextSecurePreferences.setHasSeenStickerIntroTooltip(this, true);
ApplicationDependencies.getMegaphoneRepository().onFirstEverAppLaunch();
SignalStore.registrationValues().onNewInstall();
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.ZOZO.getPackId(), BlessedPacks.ZOZO.getPackKey(), false));
ApplicationDependencies.getJobManager().add(StickerPackDownloadJob.forInstall(BlessedPacks.BANDIT.getPackId(), BlessedPacks.BANDIT.getPackKey(), false));
}
Expand Down
Expand Up @@ -14,9 +14,14 @@
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
import org.thoughtcrime.securesms.lock.v2.PinUtil;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.migrations.ApplicationMigrationActivity;
import org.thoughtcrime.securesms.migrations.ApplicationMigrations;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity;
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
import org.thoughtcrime.securesms.registration.RegistrationNavigationActivity;
import org.thoughtcrime.securesms.service.KeyCachingService;
Expand All @@ -35,6 +40,8 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
private static final int STATE_UI_BLOCKING_UPGRADE = 3;
private static final int STATE_EXPERIENCE_UPGRADE = 4;
private static final int STATE_WELCOME_PUSH_SCREEN = 5;
private static final int STATE_CREATE_PROFILE_NAME = 6;
private static final int STATE_CREATE_KBS_PIN = 7;

private SignalServiceNetworkAccess networkAccess;
private BroadcastReceiver clearKeyReceiver;
Expand Down Expand Up @@ -150,6 +157,8 @@ private Intent getIntentForState(int state) {
case STATE_UI_BLOCKING_UPGRADE: return getUiBlockingUpgradeIntent();
case STATE_WELCOME_PUSH_SCREEN: return getPushRegistrationIntent();
case STATE_EXPERIENCE_UPGRADE: return getExperienceUpgradeIntent();
case STATE_CREATE_KBS_PIN: return getCreateKbsPinIntent();
case STATE_CREATE_PROFILE_NAME: return getCreateProfileNameIntent();
default: return null;
}
}
Expand All @@ -165,11 +174,23 @@ private int getApplicationState(boolean locked) {
return STATE_WELCOME_PUSH_SCREEN;
} else if (ExperienceUpgradeActivity.isUpdate(this)) {
return STATE_EXPERIENCE_UPGRADE;
} else if (userMustSetKbsPin()) {
return STATE_CREATE_KBS_PIN;
} else if (userMustSetProfileName()) {
return STATE_CREATE_PROFILE_NAME;
} else {
return STATE_NORMAL;
}
}

private boolean userMustSetKbsPin() {
return !SignalStore.registrationValues().isRegistrationComplete() && !PinUtil.userHasPin(this);
}

private boolean userMustSetProfileName() {
return !SignalStore.registrationValues().isRegistrationComplete() && TextSecurePreferences.getProfileName(this) == ProfileName.EMPTY;
}

private Intent getCreatePassphraseIntent() {
return getRoutedIntent(PassphraseCreateActivity.class, getIntent());
}
Expand All @@ -193,6 +214,22 @@ private Intent getPushRegistrationIntent() {
return RegistrationNavigationActivity.newIntentForNewRegistration(this);
}

private Intent getCreateKbsPinIntent() {

final Intent intent;
if (userMustSetProfileName()) {
intent = getCreateProfileNameIntent();
} else {
intent = getIntent();
}

return getRoutedIntent(CreateKbsPinActivity.class, intent);
}

private Intent getCreateProfileNameIntent() {
return getRoutedIntent(EditProfileActivity.class, getIntent());
}

private Intent getRoutedIntent(Class<?> destination, @Nullable Intent nextIntent) {
final Intent intent = new Intent(this, destination);
if (nextIntent != null) intent.putExtra("next_intent", nextIntent);
Expand Down
@@ -0,0 +1,32 @@
package org.thoughtcrime.securesms.animation;

import android.animation.Animator;

import androidx.annotation.NonNull;
import androidx.core.util.Consumer;

public final class AnimationRepeatListener implements Animator.AnimatorListener {

private final Consumer<Animator> animationConsumer;

public AnimationRepeatListener(@NonNull Consumer<Animator> animationConsumer) {
this.animationConsumer = animationConsumer;
}

@Override
public final void onAnimationStart(Animator animation) {
}

@Override
public final void onAnimationEnd(Animator animation) {
}

@Override
public final void onAnimationCancel(Animator animation) {
}

@Override
public final void onAnimationRepeat(Animator animation) {
this.animationConsumer.accept(animation);
}
}
Expand Up @@ -33,18 +33,26 @@
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.MenuRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.android.material.snackbar.Snackbar;

import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.annotation.WorkerThread;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.widget.TooltipCompat;
import androidx.lifecycle.DefaultLifecycleObserver;
Expand All @@ -53,22 +61,11 @@
import androidx.lifecycle.ViewModelProviders;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;

import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
Expand All @@ -78,7 +75,6 @@
import org.thoughtcrime.securesms.MainNavigator;
import org.thoughtcrime.securesms.NewConversationActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.conversationlist.ConversationListAdapter.ItemClickListener;
import org.thoughtcrime.securesms.components.RatingManager;
import org.thoughtcrime.securesms.components.SearchToolbar;
import org.thoughtcrime.securesms.components.recyclerview.DeleteItemAnimator;
Expand All @@ -94,6 +90,7 @@
import org.thoughtcrime.securesms.components.reminder.ShareReminder;
import org.thoughtcrime.securesms.components.reminder.SystemSmsImportReminder;
import org.thoughtcrime.securesms.components.reminder.UnauthorizedReminder;
import org.thoughtcrime.securesms.conversationlist.ConversationListAdapter.ItemClickListener;
import org.thoughtcrime.securesms.conversationlist.model.MessageResult;
import org.thoughtcrime.securesms.conversationlist.model.SearchResult;
import org.thoughtcrime.securesms.database.DatabaseFactory;
Expand All @@ -106,6 +103,7 @@
import org.thoughtcrime.securesms.insights.InsightsLauncher;
import org.thoughtcrime.securesms.jobs.ServiceOutageDetectionJob;
import org.thoughtcrime.securesms.lock.RegistrationLockDialog;
import org.thoughtcrime.securesms.lock.v2.CreateKbsPinActivity;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
import org.thoughtcrime.securesms.megaphone.Megaphone;
Expand Down Expand Up @@ -231,7 +229,8 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
initializeSearchListener();

RatingManager.showRatingDialogIfNecessary(requireContext());
RegistrationLockDialog.showReminderIfNecessary(requireContext());

RegistrationLockDialog.showReminderIfNecessary(this);

TooltipCompat.setTooltipText(searchAction, getText(R.string.SearchToolbar_search_for_conversations_contacts_and_messages));
}
Expand Down Expand Up @@ -308,6 +307,14 @@ public boolean onBackPressed() {
return false;
}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == CreateKbsPinActivity.REQUEST_NEW_PIN && resultCode == CreateKbsPinActivity.RESULT_OK) {
Snackbar.make(fab, R.string.ConfirmKbsPinFragment__pin_created, Snackbar.LENGTH_LONG).show();
viewModel.onMegaphoneCompleted(Megaphones.Event.PINS_FOR_ALL);
}
}

@Override
public void onConversationClicked(@NonNull ThreadRecord threadRecord) {
getNavigator().goToConversation(threadRecord.getRecipient().getId(),
Expand Down Expand Up @@ -350,8 +357,13 @@ public void onMegaphoneNavigationRequested(@NonNull Intent intent) {
}

@Override
public void onMegaphoneToastRequested(int stringRes) {
Toast.makeText(requireContext(), stringRes, Toast.LENGTH_SHORT).show();
public void onMegaphoneNavigationRequested(@NonNull Intent intent, int requestCode) {
startActivityForResult(intent, requestCode);
}

@Override
public void onMegaphoneToastRequested(@NonNull String string) {
Snackbar.make(fab, string, Snackbar.LENGTH_SHORT).show();
}

@Override
Expand Down Expand Up @@ -472,7 +484,7 @@ private void onMegaphoneChanged(@Nullable Megaphone megaphone) {
megaphoneContainer.setVisibility(View.GONE);

if (megaphone.getOnVisibleListener() != null) {
megaphone.getOnVisibleListener().onVisible(megaphone, this);
megaphone.getOnVisibleListener().onEvent(megaphone, this);
}
}

Expand Down
@@ -1,16 +1,16 @@
package org.thoughtcrime.securesms.conversationlist;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import android.app.Application;
import android.database.ContentObserver;
import android.os.Handler;
import androidx.annotation.NonNull;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import org.thoughtcrime.securesms.conversationlist.model.SearchResult;
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
Expand Down Expand Up @@ -70,7 +70,7 @@ void onMegaphoneCompleted(@NonNull Megaphones.Event event) {
}

void onMegaphoneSnoozed(@NonNull Megaphone snoozed) {
megaphoneRepository.markSeen(snoozed);
megaphoneRepository.markSeen(snoozed.getEvent());
megaphone.postValue(null);
}

Expand Down
@@ -1,8 +1,10 @@
package org.thoughtcrime.securesms.keyvalue;

import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.thoughtcrime.securesms.lock.v2.KbsKeyboardType;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.whispersystems.signalservice.api.RegistrationLockData;
import org.whispersystems.signalservice.api.kbs.MasterKey;
Expand All @@ -17,6 +19,7 @@ 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;

Expand All @@ -32,6 +35,7 @@ public void clearRegistrationLock() {
.remove(V2_LOCK_ENABLED)
.remove(TOKEN_RESPONSE)
.remove(LOCK_LOCAL_PIN_HASH)
.remove(KEYBOARD_TYPE)
.commit();
}

Expand Down Expand Up @@ -112,4 +116,15 @@ public boolean isV2RegistrationLockEnabled() {
throw new AssertionError(e);
}
}

public void setKeyboardType(@NonNull KbsKeyboardType keyboardType) {
store.beginWrite()
.putString(KEYBOARD_TYPE, keyboardType.getCode())
.commit();
}

@CheckResult
public @NonNull KbsKeyboardType getKeyboardType() {
return KbsKeyboardType.fromCode(store.getString(KEYBOARD_TYPE, null));
}
}
Expand Up @@ -106,6 +106,10 @@ public String getString(@NonNull String key, String defaultValue) {
}
}

boolean containsKey(@NonNull String key) {
return values.containsKey(key);
}

public @NonNull Map<String, Object> getValues() {
return values;
}
Expand All @@ -114,10 +118,6 @@ public Class getType(@NonNull String key) {
return types.get(key);
}

public boolean containsKey(@NonNull String key) {
return values.containsKey(key);
}

private <E> E readValueAsType(@NonNull String key, Class<E> type, boolean nullable) {
Object value = values.get(key);
if ((value == null && nullable) || (value != null && value.getClass() == type)) {
Expand Down

0 comments on commit fb82420

Please sign in to comment.