Switch to a more flexible intro library

This commit is contained in:
Alexander Bakker 2017-08-13 19:51:54 +02:00
parent 1528aa5eaf
commit 302c4802b7
15 changed files with 263 additions and 385 deletions

View file

@ -31,7 +31,6 @@ dependencies {
compile 'com.android.support:recyclerview-v7:25.0.0'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
compile 'agency.tango.android:material-intro-screen:0.0.3'
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'me.dm7.barcodescanner:zxing:1.9'
compile 'com.android.support:cardview-v7:25.0.0'
@ -39,5 +38,6 @@ dependencies {
compile 'com.yarolegovich:lovely-dialog:1.0.4'
compile 'com.mattprecious.swirl:swirl:1.0.0'
compile 'com.madgag.spongycastle:core:1.56.0.0'
compile 'com.github.apl-devs:appintro:v4.2.2'
testCompile 'junit:junit:4.12'
}

View file

@ -30,14 +30,11 @@
</activity>
<activity
android:name=".IntroActivity"
android:label="@string/title_activity_intro"
android:theme="@style/Theme.Intro">
</activity>
<activity android:name=".AuthActivity">
</activity>
<activity android:name=".PreferencesActivity">
</activity>
<activity android:name=".SetPasswordActivity">
</activity>
</application>
</manifest>

View file

@ -2,12 +2,17 @@ package me.impy.aegis;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.github.paolorotolo.appintro.ISlidePolicy;
import com.github.paolorotolo.appintro.ISlideSelectionListener;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
@ -17,80 +22,29 @@ import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import agency.tango.materialintroscreen.SlideFragment;
import me.impy.aegis.crypto.CryptoUtils;
import me.impy.aegis.crypto.slots.PasswordSlot;
import me.impy.aegis.crypto.slots.Slot;
public class CustomAuthenticatedSlide extends SlideFragment {
public class CustomAuthenticatedSlide extends Fragment implements ISlidePolicy, ISlideSelectionListener {
private int cryptType;
private EditText textPassword;
private EditText textPasswordConfirm;
private int bgColor;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_authenticated_slide, container, false);
final View view = inflater.inflate(R.layout.fragment_authenticated_slide, container, false);
textPassword = (EditText) view.findViewById(R.id.text_password);
textPasswordConfirm = (EditText) view.findViewById(R.id.text_password_confirm);
view.findViewById(R.id.main).setBackgroundColor(bgColor);
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (!isVisibleToUser) {
return;
}
Intent intent = getActivity().getIntent();
cryptType = intent.getIntExtra("cryptType", 1337);
switch(cryptType) {
case CustomAuthenticationSlide.CRYPT_TYPE_NONE:
break;
case CustomAuthenticationSlide.CRYPT_TYPE_PASS:
break;
case CustomAuthenticationSlide.CRYPT_TYPE_FINGER:
break;
default:
throw new RuntimeException();
}
}
@Override
public int backgroundColor() {
return R.color.colorHeaderSuccess;
}
@Override
/*@Override
public int buttonsColor() {
return R.color.colorAccent;
}
@Override
public boolean canMoveFurther() {
switch(cryptType) {
case CustomAuthenticationSlide.CRYPT_TYPE_NONE:
return true;
case CustomAuthenticationSlide.CRYPT_TYPE_PASS:
char[] password = getEditTextChars(textPassword);
char[] passwordConfirm = getEditTextChars(textPasswordConfirm);
boolean equal = password.length != 0 && Arrays.equals(password, passwordConfirm);
CryptoUtils.zero(password);
CryptoUtils.zero(passwordConfirm);
return equal;
case CustomAuthenticationSlide.CRYPT_TYPE_FINGER:
return false;
default:
throw new RuntimeException();
}
}
@Override
public String cantMoveFurtherErrorMessage() {
return "Passwords should be equal and non-empty";
}
}*/
public int getCryptType() {
return cryptType;
@ -121,4 +75,57 @@ public class CustomAuthenticatedSlide extends SlideFragment {
editable.getChars(0, editable.length(), chars, 0);
return chars;
}
@Override
public void onSlideSelected() {
Intent intent = getActivity().getIntent();
cryptType = intent.getIntExtra("cryptType", 1337);
switch(cryptType) {
case CustomAuthenticationSlide.CRYPT_TYPE_NONE:
break;
case CustomAuthenticationSlide.CRYPT_TYPE_PASS:
break;
case CustomAuthenticationSlide.CRYPT_TYPE_FINGER:
break;
default:
throw new RuntimeException();
}
}
public void setBgColor(int color) {
bgColor = color;
}
@Override
public void onSlideDeselected() {
}
@Override
public boolean isPolicyRespected() {
switch(cryptType) {
case CustomAuthenticationSlide.CRYPT_TYPE_NONE:
return true;
case CustomAuthenticationSlide.CRYPT_TYPE_PASS:
char[] password = getEditTextChars(textPassword);
char[] passwordConfirm = getEditTextChars(textPasswordConfirm);
boolean equal = password.length != 0 && Arrays.equals(password, passwordConfirm);
CryptoUtils.zero(password);
CryptoUtils.zero(passwordConfirm);
return equal;
case CustomAuthenticationSlide.CRYPT_TYPE_FINGER:
return false;
default:
throw new RuntimeException();
}
}
@Override
public void onUserIllegallyRequestedNextPage() {
View view = getView();
if (view != null) {
Snackbar snackbar = Snackbar.make(getView(), "Passwords should be equal and non-empty", Snackbar.LENGTH_LONG);
snackbar.show();
}
}
}

View file

@ -7,24 +7,28 @@ import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import agency.tango.materialintroscreen.SlideFragment;
import com.github.paolorotolo.appintro.ISlidePolicy;
public class CustomAuthenticationSlide extends SlideFragment {
public static final int CRYPT_TYPE_NONE = 0;
public static final int CRYPT_TYPE_PASS = 1;
public static final int CRYPT_TYPE_FINGER = 2;
public class CustomAuthenticationSlide extends Fragment implements ISlidePolicy {
public static final int CRYPT_TYPE_INVALID = 0;
public static final int CRYPT_TYPE_NONE = 1;
public static final int CRYPT_TYPE_PASS = 2;
public static final int CRYPT_TYPE_FINGER = 3;
private RadioGroup buttonGroup;
private int bgColor;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -34,7 +38,7 @@ public class CustomAuthenticationSlide extends SlideFragment {
buttonGroup = (RadioGroup) view.findViewById(R.id.rg_authenticationMethod);
buttonGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == -1) {
return;
}
@ -72,26 +76,27 @@ public class CustomAuthenticationSlide extends SlideFragment {
}
}
view.findViewById(R.id.main).setBackgroundColor(bgColor);
return view;
}
@Override
public int backgroundColor() {
return R.color.colorHeaderSuccess;
public void setBgColor(int color) {
bgColor = color;
}
@Override
public int buttonsColor() {
return R.color.colorAccent;
}
@Override
public boolean canMoveFurther() {
public boolean isPolicyRespected() {
return buttonGroup.getCheckedRadioButtonId() != -1;
}
@Override
public String cantMoveFurtherErrorMessage() {
return "Please select an authentication method";
public void onUserIllegallyRequestedNextPage() {
Snackbar snackbar = Snackbar.make(getView(), "Please select an authentication method", Snackbar.LENGTH_LONG);
snackbar.show();
}
/*@Override
public int buttonsColor() {
return R.color.colorAccent;
}*/
}

View file

@ -1,9 +1,5 @@
package me.impy.aegis;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetDialogFragment;
@ -11,7 +7,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;
public class EditProfileBottomSheetdialog extends BottomSheetDialogFragment {
LinearLayout copyLayout;

View file

@ -5,17 +5,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.support.v4.app.Fragment;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.NoSuchAlgorithmException;
import com.github.paolorotolo.appintro.AppIntro;
import com.github.paolorotolo.appintro.AppIntroFragment;
import com.github.paolorotolo.appintro.model.SliderPage;
import javax.crypto.Cipher;
import agency.tango.materialintroscreen.MaterialIntroActivity;
import agency.tango.materialintroscreen.MessageButtonBehaviour;
import agency.tango.materialintroscreen.SlideFragmentBuilder;
import me.impy.aegis.crypto.CryptResult;
import me.impy.aegis.crypto.MasterKey;
import me.impy.aegis.crypto.slots.PasswordSlot;
@ -23,63 +20,77 @@ import me.impy.aegis.crypto.slots.SlotCollection;
import me.impy.aegis.db.Database;
import me.impy.aegis.db.DatabaseFile;
public class IntroActivity extends MaterialIntroActivity {
public class IntroActivity extends AppIntro {
public static final int RESULT_OK = 0;
public static final int RESULT_EXCEPTION = 1;
private CustomAuthenticatedSlide authenticatedSlide;
private CustomAuthenticationSlide authenticationSlide;
private Fragment endSlide;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hideBackButton();
showSkipButton(false);
//showPagerIndicator(false);
setGoBackLock(true);
// TODO: remove this once github.com/apl-devs/AppIntro/issues/347 is fixed
setSwipeLock(true);
addSlide(new SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.intro_shield)
.title("Welcome")
.description("Aegis is a brand new open source(!) authenticator app which generates tokens for your accounts.")
.build());
SliderPage homeSliderPage = new SliderPage();
homeSliderPage.setTitle("Welcome");
homeSliderPage.setDescription("Aegis is a secure, free and open source 2FA app");
homeSliderPage.setImageDrawable(R.drawable.intro_shield);
homeSliderPage.setBgColor(getResources().getColor(R.color.colorPrimary));
addSlide(AppIntroFragment.newInstance(homeSliderPage));
addSlide(new SlideFragmentBuilder()
.backgroundColor(R.color.colorAccent)
.buttonsColor(R.color.colorPrimary)
.neededPermissions(new String[]{Manifest.permission.CAMERA})
.image(R.drawable.intro_scanner)
.title("Permissions")
.description("Aegis needs permission to your camera in order to function properly. This is needed to scan QR codes.")
.build(),
new MessageButtonBehaviour(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
}, "Permission granted"));
addSlide(new CustomAuthenticationSlide());
SliderPage permSliderPage = new SliderPage();
permSliderPage.setTitle("Permissions");
permSliderPage.setDescription("Aegis needs permission to use your camera in order to scan QR codes.");
permSliderPage.setImageDrawable(R.drawable.intro_scanner);
permSliderPage.setBgColor(getResources().getColor(R.color.colorAccent));
addSlide(AppIntroFragment.newInstance(permSliderPage));
askForPermissions(new String[]{Manifest.permission.CAMERA}, 2);
authenticationSlide = new CustomAuthenticationSlide();
authenticationSlide.setBgColor(getResources().getColor(R.color.colorHeaderSuccess));
addSlide(authenticationSlide);
authenticatedSlide = new CustomAuthenticatedSlide();
authenticatedSlide.setBgColor(getResources().getColor(R.color.colorPrimary));
addSlide(authenticatedSlide);
addSlide(new SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.intro_shield)
.title("All done!")
.description("Aegis has been set up and is ready to go.")
.build());
SliderPage endSliderPage = new SliderPage();
endSliderPage.setTitle("All done!");
endSliderPage.setDescription("Aegis has been set up and is ready to go.");
endSliderPage.setImageDrawable(R.drawable.intro_shield);
endSliderPage.setBgColor(getResources().getColor(R.color.colorPrimary));
endSlide = AppIntroFragment.newInstance(endSliderPage);
addSlide(endSlide);
}
private void setException(Exception e) {
Intent result = new Intent();
result.putExtra("exception", e);
setResult(RESULT_EXCEPTION, result);
finish();
}
@Override
public void onFinish() {
super.onFinish();
public void onSlideChanged(Fragment oldFragment, Fragment newFragment) {
// skip to the last slide if no encryption will be used
if (oldFragment == authenticationSlide && newFragment != endSlide) {
Intent intent = getIntent();
int cryptType = intent.getIntExtra("cryptType", CustomAuthenticationSlide.CRYPT_TYPE_INVALID);
if (cryptType == CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
// TODO: no magic indices
getPager().setCurrentItem(5);
}
}
}
@Override
public void onDonePressed(Fragment currentFragment) {
super.onDonePressed(currentFragment);
// create the database and database file
Database database = new Database();
@ -142,5 +153,6 @@ public class IntroActivity extends MaterialIntroActivity {
// TODO: show the intro if we can't find any database files
SharedPreferences prefs = this.getSharedPreferences("me.impy.aegis", Context.MODE_PRIVATE);
prefs.edit().putBoolean("passedIntro", true).apply();
finish();
}
}

View file

@ -409,9 +409,4 @@ public class MainActivity extends AppCompatActivity {
e.printStackTrace();
}
}
private boolean causeIsKeyUserNotAuthenticated(Exception e) {
// TODO: is there a way to catch "Key user not authenticated" specifically aside from checking the exception message?
return e.getCause().getMessage().equals("Key user not authenticated");
}
}

View file

@ -1,13 +0,0 @@
package me.impy.aegis;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class SetPasswordActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_password);
}
}

View file

@ -1,35 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="me.impy.aegis.IntroActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_intro"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email"/>
</android.support.design.widget.CoordinatorLayout>

View file

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_set_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="me.impy.aegis.SetPasswordActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="@+id/textView4"
android:text="@string/set_password"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/editText2"
android:layout_below="@+id/textView3"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_alignParentEnd="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:text="@string/set_password_confirm"
android:layout_marginTop="74dp"
android:layout_below="@+id/textView4"
/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/editText"
android:layout_marginTop="8dp"
android:layout_below="@+id/textView4"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"/>
<Button
android:text="Continue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_below="@+id/editText2"
android:layout_alignParentEnd="true"
android:layout_marginTop="26dp"/>
</RelativeLayout>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_intro"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="me.impy.aegis.IntroActivity"
tools:showIn="@layout/activity_intro">
</RelativeLayout>

View file

@ -1,75 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<agency.tango.materialintroscreen.parallax.ParallaxLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:orientation="vertical"
android:paddingTop="30dp">
android:padding="32dp">
<TextView
android:text="@string/authentication_method_set_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/primary_text_inverted"
android:id="@+id/textView2" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="32dp">
android:layout_marginTop="12dp">
<TextView
android:text="@string/authentication_method_set_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/primary_text_inverted"
android:id="@+id/textView2" />
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="@+id/textView4"
android:text="@string/set_password"/>
<LinearLayout
android:orientation="vertical"
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="12dp">
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/text_password"
android:layout_below="@+id/textView3"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_alignParentEnd="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="@+id/textView4"
android:text="@string/set_password"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:text="@string/set_password_confirm"
android:layout_marginTop="20dp"
android:layout_below="@+id/textView4"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/text_password"
android:layout_below="@+id/textView3"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_alignParentEnd="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:text="@string/set_password_confirm"
android:layout_marginTop="20dp"
android:layout_below="@+id/textView4"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/text_password_confirm"
android:layout_marginTop="8dp"
android:layout_below="@+id/textView4"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"/>
</LinearLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/text_password_confirm"
android:layout_marginTop="8dp"
android:layout_below="@+id/textView4"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"/>
</LinearLayout>
</agency.tango.materialintroscreen.parallax.ParallaxLinearLayout>
</LinearLayout>

View file

@ -1,100 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<agency.tango.materialintroscreen.parallax.ParallaxLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorHeaderSuccess"
android:orientation="vertical"
android:paddingBottom="164dp"
android:paddingTop="30dp">
android:padding="32dp">
<TextView
android:text="@string/choose_authentication_method"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/primary_text_inverted"
android:id="@+id/textView2" />
<LinearLayout
android:orientation="vertical"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="32dp">
android:layout_height="200dp"
android:layout_marginTop="12dp">
<TextView
android:text="@string/choose_authentication_method"
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/primary_text_inverted"
android:id="@+id/textView2" />
android:id="@+id/rg_authenticationMethod"
android:layout_height="187dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="12dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:id="@+id/rb_none"
android:text="@string/authentication_method_none"/>
<RadioGroup
<TextView
android:text="@string/authentication_method_none_description"
android:layout_width="match_parent"
android:id="@+id/rg_authenticationMethod"
android:layout_height="187dp">
android:textColor="@color/secondary_text_inverted"
android:layout_marginTop="-5dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:id="@+id/rb_none"
android:text="@string/authentication_method_none"/>
<RadioButton
android:text="@string/authentication_method_password"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"
android:id="@+id/rb_password"/>
<TextView
android:text="@string/authentication_method_none_description"
android:layout_width="match_parent"
android:textColor="@color/secondary_text_inverted"
android:layout_marginTop="-5dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
/>
<TextView
android:text="@string/authentication_method_password_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-5dp"
android:textColor="@color/secondary_text_inverted"
android:layout_marginStart="32dp"/>
<RadioButton
android:text="@string/authentication_method_password"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"
android:id="@+id/rb_password"/>
<RadioButton
android:text="@string/authentication_method_fingerprint"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"
android:id="@+id/rb_fingerprint"
android:visibility="invisible"/>
<TextView
android:id="@+id/text_rb_fingerprint"
android:text="@string/authentication_method_fingerprint_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-5dp"
android:textColor="@color/secondary_text_inverted"
android:layout_marginStart="32dp"
android:visibility="invisible"/>
<TextView
android:text="@string/authentication_method_password_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-5dp"
android:textColor="@color/secondary_text_inverted"
android:layout_marginStart="32dp"/>
<RadioButton
android:text="@string/authentication_method_fingerprint"
android:layout_width="match_parent"
android:textSize="16sp"
android:layout_height="wrap_content"
android:id="@+id/rb_fingerprint"
android:visibility="invisible"/>
<TextView
android:id="@+id/text_rb_fingerprint"
android:text="@string/authentication_method_fingerprint_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-5dp"
android:textColor="@color/secondary_text_inverted"
android:layout_marginStart="32dp"
android:visibility="invisible"/>
</RadioGroup>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
</LinearLayout>
</RadioGroup>
</LinearLayout>
</agency.tango.materialintroscreen.parallax.ParallaxLinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
</LinearLayout>
</LinearLayout>

View file

@ -24,6 +24,11 @@
<item name="background">@null</item>
</style>
<style name="Theme.Intro" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>

View file

@ -15,6 +15,7 @@ buildscript {
allprojects {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}