Merge branch '176-setupactivity-warnings-api10' into 'master'

Fix SetupActivity warnings for API 10

Closes #176.

The manual setting of the error message color also (strangely) stops the message from disappearing every second character. I'm not complaining ^_^

I guessed that the text color problem probably stopped occurring from API 14 (at the big 4.0 overhaul), but it would be great if someone could confirm.

See merge request !40
This commit is contained in:
akwizgran
2015-12-31 12:03:44 +00:00
7 changed files with 175 additions and 126 deletions

View File

@@ -6,8 +6,9 @@ dependencies {
compile fileTree(dir: '../briar-core/libs', include: '*.jar')
compile project(':briar-core')
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile "com.android.support:support-v4:23.1.1"
compile "com.android.support:appcompat-v7:23.1.1"
compile "com.android.support:design:23.1.1"
}
android {

View File

@@ -27,7 +27,6 @@
android:hint="@string/password_hint"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:lines="1"
android:maxLines="1" />
<Button

View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/margin_activity_vertical"
android:paddingEnd="@dimen/margin_activity_horizontal"
android:paddingLeft="@dimen/margin_activity_horizontal"
android:paddingRight="@dimen/margin_activity_horizontal"
android:paddingStart="@dimen/margin_activity_horizontal"
android:paddingTop="@dimen/margin_activity_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/choose_nickname"
android:textSize="@dimen/text_size_medium"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/nickname_entry_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<EditText
android:id="@+id/nickname_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text|textCapWords"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/choose_password"
android:textSize="@dimen/text_size_medium"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/password_entry_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<EditText
android:id="@+id/password_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/confirm_password"
android:textSize="@dimen/text_size_medium"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/password_confirm_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<EditText
android:id="@+id/password_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:imeOptions="actionDone"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
<org.briarproject.android.util.StrengthMeter
android:id="@+id/strength_meter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"/>
<Button
android:id="@+id/create_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="@string/create_account_button"/>
<ProgressBar
android:id="@+id/progress_wheel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>

View File

@@ -29,7 +29,6 @@ import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_HOME;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
public class PasswordActivity extends BaseActivity {
@@ -63,11 +62,11 @@ public class PasswordActivity extends BaseActivity {
password = (EditText) findViewById(R.id.edit_password);
password.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == IME_ACTION_DONE) {
validatePassword(encrypted, password.getText());
}
return false;
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
hideSoftKeyboard();
validatePassword(encrypted, password.getText());
return true;
}
});
}

View File

@@ -4,20 +4,20 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import org.briarproject.R;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.android.util.StrengthMeter;
import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.crypto.CryptoComponent;
@@ -35,38 +35,35 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import roboguice.inject.InjectView;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.text.InputType.TYPE_CLASS_TEXT;
import static android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS;
import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
public class SetupActivity extends BaseActivity implements OnClickListener,
OnEditorActionListener {
OnEditorActionListener {
private static final Logger LOG =
Logger.getLogger(SetupActivity.class.getName());
@Inject @CryptoExecutor private Executor cryptoExecutor;
@Inject private PasswordStrengthEstimator strengthEstimator;
private EditText nicknameEntry = null;
private EditText passwordEntry = null, passwordConfirmation = null;
private StrengthMeter strengthMeter = null;
private Button createAccountButton = null;
private ProgressBar progress = null;
@InjectView(R.id.nickname_entry_wrapper) TextInputLayout nicknameEntryWrapper;
@InjectView(R.id.password_entry_wrapper) TextInputLayout passwordEntryWrapper;
@InjectView(R.id.password_confirm_wrapper) TextInputLayout passwordConfirmationWrapper;
@InjectView(R.id.nickname_entry) EditText nicknameEntry;
@InjectView(R.id.password_entry) EditText passwordEntry;
@InjectView(R.id.password_confirm) EditText passwordConfirmation;
@InjectView(R.id.strength_meter) StrengthMeter strengthMeter;
@InjectView(R.id.create_account) Button createAccountButton;
@InjectView(R.id.progress_wheel) ProgressBar progress;
// Fields that are accessed from background threads must be volatile
@Inject private volatile CryptoComponent crypto;
@@ -77,99 +74,32 @@ OnEditorActionListener {
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_setup);
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(MATCH_MATCH);
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
int pad = LayoutUtils.getPadding(this);
layout.setPadding(pad, pad, pad, pad);
TextView chooseNickname = new TextView(this);
chooseNickname.setGravity(CENTER);
chooseNickname.setTextSize(18);
chooseNickname.setText(R.string.choose_nickname);
layout.addView(chooseNickname);
nicknameEntry = new EditText(this) {
TextWatcher tw = new TextWatcher() {
@Override
protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) {
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
enableOrDisableContinueButton();
}
};
nicknameEntry.setId(1);
nicknameEntry.setMaxLines(1);
int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_WORDS;
nicknameEntry.setInputType(inputType);
layout.addView(nicknameEntry);
TextView choosePassword = new TextView(this);
choosePassword.setGravity(CENTER);
choosePassword.setTextSize(18);
choosePassword.setPadding(0, pad, 0, 0);
choosePassword.setText(R.string.choose_password);
layout.addView(choosePassword);
passwordEntry = new EditText(this) {
@Override
protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) {
enableOrDisableContinueButton();
public void afterTextChanged(Editable s) {
}
};
passwordEntry.setId(2);
passwordEntry.setMaxLines(1);
inputType = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD;
passwordEntry.setInputType(inputType);
layout.addView(passwordEntry);
TextView confirmPassword = new TextView(this);
confirmPassword.setGravity(CENTER);
confirmPassword.setTextSize(18);
confirmPassword.setPadding(0, pad, 0, 0);
confirmPassword.setText(R.string.confirm_password);
layout.addView(confirmPassword);
passwordConfirmation = new EditText(this) {
@Override
protected void onTextChanged(CharSequence text, int start,
int lengthBefore, int lengthAfter) {
enableOrDisableContinueButton();
}
};
passwordConfirmation.setId(3);
passwordConfirmation.setMaxLines(1);
inputType = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD;
passwordConfirmation.setInputType(inputType);
nicknameEntry.addTextChangedListener(tw);
passwordEntry.addTextChangedListener(tw);
passwordConfirmation.addTextChangedListener(tw);
passwordConfirmation.setOnEditorActionListener(this);
layout.addView(passwordConfirmation);
strengthMeter = new StrengthMeter(this);
strengthMeter.setPadding(pad, pad, pad, pad);
strengthMeter.setVisibility(INVISIBLE);
layout.addView(strengthMeter);
createAccountButton = new Button(this);
createAccountButton.setLayoutParams(WRAP_WRAP);
createAccountButton.setText(R.string.create_account_button);
createAccountButton.setEnabled(false);
createAccountButton.setOnClickListener(this);
layout.addView(createAccountButton);
progress = new ProgressBar(this);
progress.setLayoutParams(WRAP_WRAP);
progress.setPadding(0, pad, 0, 0);
progress.setIndeterminate(true);
progress.setVisibility(GONE);
layout.addView(progress);
ScrollView scroll = new ScrollView(this);
scroll.addView(layout);
setContentView(scroll);
}
private void enableOrDisableContinueButton() {
@@ -184,21 +114,22 @@ OnEditorActionListener {
boolean passwordsMatch = firstPassword.equals(secondPassword);
float strength = strengthEstimator.estimateStrength(firstPassword);
strengthMeter.setStrength(strength);
if (nicknameLength > MAX_AUTHOR_NAME_LENGTH)
nicknameEntry.setError(getString(R.string.name_too_long));
if (firstPassword.length() > 0 && strength < WEAK)
passwordEntry.setError(getString(R.string.password_too_weak));
if (secondPassword.length() > 0 && !passwordsMatch)
passwordConfirmation.setError(getString(R.string.passwords_do_not_match));
AndroidUtils.setError(nicknameEntryWrapper,
getString(R.string.name_too_long),
nicknameLength > MAX_AUTHOR_NAME_LENGTH);
AndroidUtils.setError(passwordEntryWrapper,
getString(R.string.password_too_weak),
firstPassword.length() > 0 && strength < WEAK);
AndroidUtils.setError(passwordConfirmationWrapper,
getString(R.string.passwords_do_not_match),
secondPassword.length() > 0 && !passwordsMatch);
createAccountButton.setEnabled(nicknameLength > 0
&& nicknameLength <= MAX_AUTHOR_NAME_LENGTH
&& passwordsMatch && strength >= WEAK);
}
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// Hide the soft keyboard
Object o = getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
hideSoftKeyboard();
return true;
}

View File

@@ -2,6 +2,7 @@ package org.briarproject.android.util;
import android.annotation.SuppressLint;
import android.os.Build;
import android.support.design.widget.TextInputLayout;
import java.util.ArrayList;
import java.util.Arrays;
@@ -23,4 +24,12 @@ public class AndroidUtils {
}
return Collections.unmodifiableList(abis);
}
public static void setError(TextInputLayout til, String error, boolean condition) {
if (condition) {
if (til.getError() == null)
til.setError(error);
} else
til.setError(null);
}
}

View File

@@ -1,5 +1,15 @@
package org.briarproject.android.util;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.util.AttributeSet;
import android.widget.ProgressBar;
import static android.graphics.Color.BLACK;
import static android.graphics.Paint.Style.FILL;
import static android.graphics.Paint.Style.STROKE;
@@ -9,14 +19,6 @@ import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG
import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.widget.ProgressBar;
public class StrengthMeter extends ProgressBar {
@@ -30,7 +32,11 @@ public class StrengthMeter extends ProgressBar {
private final ShapeDrawable bar;
public StrengthMeter(Context context) {
super(context, null, android.R.attr.progressBarStyleHorizontal);
this(context, null);
}
public StrengthMeter(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
bar = new ShapeDrawable();
bar.getPaint().setColor(RED);
ClipDrawable clip = new ClipDrawable(bar, LEFT, HORIZONTAL);