Skip to content
Snippets Groups Projects
Commit 27edc2e3 authored by Ernir Erlingsson's avatar Ernir Erlingsson
Browse files

code and ui refactoring in the Password activity, encapsulation and wrappers.

parent d0342f9a
No related branches found
No related tags found
1 merge request!1040 forgotten password
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/margin_activity_vertical"
android:paddingEnd="@dimen/margin_activity_horizontal"
android:paddingStart="@dimen/margin_activity_horizontal"
android:paddingTop="@dimen/margin_activity_vertical">
<TextView
android:id="@+id/title_password"
style="@style/BriarTextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="@dimen/margin_large"
android:text="@string/enter_password" />
<EditText
android:id="@+id/edit_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title_password"
android:hint="@string/password_hint"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:lines="1"
android:maxLines="1" />
<Button
android:id="@+id/btn_sign_in"
style="@style/BriarButton.Default"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/edit_password"
android:layout_marginTop="@dimen/margin_xlarge"
android:onClick="onSignInClick"
android:text="@string/sign_in_button" />
<ProgressBar
android:id="@+id/progress_wheel"
style="?android:attr/progressBarStyleInverse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@id/btn_sign_in"
android:visibility="invisible" />
<TextView
style="@style/BriarTextBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_sign_in"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/margin_large"
android:clickable="true"
android:onClick="onForgottenPasswordClick"
android:text="@string/forgotten_password"
android:textColor="?android:attr/textColorLink" />
</RelativeLayout>
\ No newline at end of file
......@@ -9,4 +9,9 @@
<item name="android:textColor">@color/action_bar_text</item>
<item name="android:background">@color/action_bar_background</item>
</style>
<style name="BriarButton.Default">
<item name="android:textAllCaps">true</item>
</style>
</resources>
\ No newline at end of file
......@@ -14,4 +14,6 @@
<color name="no_posts">#AAAAAA</color>
<color name="settings_title_text">#2D3E50</color>
<color name="settings_title_underline">#2D3E50</color>
<color name="text_link">#2D3E50</color>
</resources>
\ No newline at end of file
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="margin_activity_horizontal">16dp</dimen>
<dimen name="margin_activity_vertical">16dp</dimen>
<dimen name="margin_seperator">1dp</dimen>
<dimen name="margin_tiny">2dp</dimen>
<dimen name="margin_small">4dp</dimen>
<dimen name="margin_medium">8dp</dimen>
<dimen name="margin_large">16dp</dimen>
<dimen name="margin_xlarge">32dp</dimen>
<!-- v2 dimens -->
<dimen name="text_size_tiny">12sp</dimen>
<dimen name="text_size_small">14sp</dimen>
<dimen name="text_size_medium">16sp</dimen>
<dimen name="text_size_large">20sp</dimen>
<dimen name="text_size_xlarge">34sp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Briar</string>
<string name="crash_report_title">Briar Crash Report</string>
<string name="ongoing_notification_title">Signed into Briar</string>
......@@ -13,6 +15,8 @@
<string name="passwords_do_not_match">Passwords do not match</string>
<string name="create_account_button">Create Account</string>
<string name="enter_password">Enter your password:</string>
<string name="password_hint">Password</string>
<string name="forgotten_password">I have forgotten my password</string>
<string name="try_again">Wrong password, try again:</string>
<string name="sign_in_button">Sign In</string>
<string name="startup_failed_notification_title">Briar could not start</string>
......
......@@ -12,4 +12,21 @@
<style name="WindowTitleBackground">
<item name="android:background">@color/action_bar_background</item>
</style>
<style name="BriarButton">
<item name="android:textSize">@dimen/text_size_medium</item>
<item name="android:padding">@dimen/margin_large</item>
</style>
<style name="BriarButton.Default"/>
<style name="BriarTextTitle">
<item name="android:textSize">@dimen/text_size_medium</item>
<item name="android:textColor">@android:color/primary_text_light</item>
</style>
<style name="BriarTextBody">
<item name="android:textSize">@dimen/text_size_small</item>
<item name="android:textColor">@android:color/primary_text_light</item>
</style>
</resources>
\ No newline at end of file
package org.briarproject.android;
import static android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY;
import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.inputmethod.InputMethodManager;
import roboguice.activity.RoboActivity;
public abstract class BaseActivity extends RoboActivity {
private final static String PREFS_DB = "db";
private final static String KEY_DB_KEY = "key";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
}
private SharedPreferences getBriarPrefs(String prefsName) {
return getSharedPreferences(prefsName, MODE_PRIVATE);
}
protected String getDbKeyInHex() {
return getBriarPrefs(PREFS_DB).getString(KEY_DB_KEY, null);
}
private void clearPrefs(String prefsName) {
SharedPreferences.Editor editor = getBriarPrefs(prefsName).edit();
editor.clear();
editor.apply();
}
protected void clearDbPrefs() {
this.clearPrefs(PREFS_DB);
}
protected void gotoAndFinish(Class classInstance, int resultCode) {
if (resultCode != Integer.MIN_VALUE)
this.setResult(resultCode);
this.startActivity(new Intent(this, classInstance));
this.finish();
}
protected void hideSoftKeyboard()
{
Object o = getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
}
}
......@@ -25,7 +25,7 @@ import android.os.IBinder;
import android.view.inputmethod.InputMethodManager;
@SuppressLint("Registered")
public class BriarActivity extends RoboActivity {
public class BriarActivity extends BaseActivity {
public static final int REQUEST_PASSWORD = 1;
......@@ -45,7 +45,6 @@ public class BriarActivity extends RoboActivity {
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
if (databaseConfig.getEncryptionKey() != null) startAndBindService();
}
......
package org.briarproject.android;
import static android.text.InputType.TYPE_CLASS_TEXT;
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.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 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 java.io.File;
import java.util.concurrent.Executor;
......@@ -19,37 +9,32 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
import org.briarproject.R;
import org.briarproject.android.util.FixedVerticalSpace;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseConfig;
import org.briarproject.util.StringUtils;
import roboguice.activity.RoboActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class PasswordActivity extends RoboActivity {
public class PasswordActivity extends BaseActivity {
@Inject @CryptoExecutor private Executor cryptoExecutor;
private TextView enterPassword = null;
private EditText passwordEntry = null;
private Button signInButton = null;
private ProgressBar progress = null;
private Button mSignInButton;
private ProgressBar mProgress;
private TextView mTitle;
private EditText mPassword;
private byte[] encrypted;
// Fields that are accessed from background threads must be volatile
@Inject private volatile CryptoComponent crypto;
......@@ -59,66 +44,42 @@ public class PasswordActivity extends RoboActivity {
public void onCreate(Bundle state) {
super.onCreate(state);
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
SharedPreferences prefs = getSharedPreferences("db", MODE_PRIVATE);
String hex = prefs.getString("key", null);
String hex = this.getDbKeyInHex();
if (hex == null || !databaseConfig.databaseExists()) {
// Storage has been deleted - clean up and return to setup
prefs.edit().clear().commit();
delete(databaseConfig.getDatabaseDirectory());
setResult(RESULT_CANCELED);
startActivity(new Intent(this, SetupActivity.class));
finish();
this.clearDbPrefs();
return;
}
final byte[] encrypted = StringUtils.fromHexString(hex);
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);
enterPassword = new TextView(this);
enterPassword.setGravity(CENTER);
enterPassword.setTextSize(18);
enterPassword.setText(R.string.enter_password);
layout.addView(enterPassword);
passwordEntry = new EditText(this);
passwordEntry.setId(1);
passwordEntry.setMaxLines(1);
int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD;
passwordEntry.setInputType(inputType);
passwordEntry.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int action, KeyEvent e) {
validatePassword(encrypted, passwordEntry.getText());
return true;
this.encrypted = StringUtils.fromHexString(hex);
this.setContentView(R.layout.activity_password);
this.mSignInButton = (Button)findViewById(R.id.btn_sign_in);
this.mProgress = (ProgressBar)findViewById(R.id.progress_wheel);
this.mTitle = (TextView)findViewById(R.id.title_password);
this.mPassword = (EditText)findViewById(R.id.edit_password);
this.mPassword.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
validatePassword(encrypted, PasswordActivity.this.mPassword.getText());
}
return false;
}
});
layout.addView(passwordEntry);
}
@Override
protected void clearDbPrefs() {
super.clearDbPrefs();
this.delete(databaseConfig.getDatabaseDirectory());
this.gotoAndFinish(SetupActivity.class, RESULT_CANCELED);
}
// Adjusting the padding of buttons and EditTexts has the wrong results
layout.addView(new FixedVerticalSpace(this));
public void onSignInClick(View v) {
this.validatePassword(this.encrypted, this.mPassword.getText());
}
signInButton = new Button(this);
signInButton.setLayoutParams(WRAP_WRAP);
signInButton.setText(R.string.sign_in_button);
signInButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
validatePassword(encrypted, passwordEntry.getText());
}
});
layout.addView(signInButton);
progress = new ProgressBar(this);
progress.setLayoutParams(WRAP_WRAP);
progress.setIndeterminate(true);
progress.setVisibility(GONE);
layout.addView(progress);
setContentView(layout);
public void onForgottenPasswordClick(View v) {
this.clearDbPrefs();
}
private void delete(File f) {
......@@ -127,13 +88,10 @@ public class PasswordActivity extends RoboActivity {
}
private void validatePassword(final byte[] encrypted, Editable e) {
if (progress == null) return; // Not created yet
// Hide the soft keyboard
Object o = getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
this.hideSoftKeyboard();
// Replace the button with a progress bar
signInButton.setVisibility(GONE);
progress.setVisibility(VISIBLE);
this.mSignInButton.setVisibility(View.INVISIBLE);
this.mProgress.setVisibility(VISIBLE);
// Decrypt the database key in a background thread
final String password = e.toString();
cryptoExecutor.execute(new Runnable() {
......@@ -152,10 +110,9 @@ public class PasswordActivity extends RoboActivity {
private void tryAgain() {
runOnUiThread(new Runnable() {
public void run() {
enterPassword.setText(R.string.try_again);
passwordEntry.setText("");
signInButton.setVisibility(VISIBLE);
progress.setVisibility(GONE);
PasswordActivity.this.mTitle.setText(R.string.try_again);
PasswordActivity.this.mSignInButton.setVisibility(VISIBLE);
PasswordActivity.this.mProgress.setVisibility(GONE);
}
});
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment