Move preferences into a global preferences controller.
This commit is contained in:
parent
7f8a36e32e
commit
060ec0b5cd
@ -108,7 +108,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:textColor="#FFFFFF"
|
android:textColor="#FFFFFF"
|
||||||
android:textSize="32sp"
|
android:textSize="28sp"
|
||||||
tools:text="LuxdZozvDuma4["
|
tools:text="LuxdZozvDuma4["
|
||||||
android:onClick="copySitePassword" />
|
android:onClick="copySitePassword" />
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<string name="siteCounter_hint">Counter</string>
|
<string name="siteCounter_hint">Counter</string>
|
||||||
<string name="siteVersion_hint">Algorithm</string>
|
<string name="siteVersion_hint">Algorithm</string>
|
||||||
<string name="empty" />
|
<string name="empty" />
|
||||||
<string name="btn_tests">Integrity Tests</string>
|
<string name="btn_tests">Integrity Tests ❯</string>
|
||||||
<string name="tests_unavailable">Test suite unavailable.</string>
|
<string name="tests_unavailable">Test suite unavailable.</string>
|
||||||
<string name="tests_btn_unavailable">Retest</string>
|
<string name="tests_btn_unavailable">Retest</string>
|
||||||
<string name="tests_testing">Testing device\'s password generation integrity…</string>
|
<string name="tests_testing">Testing device\'s password generation integrity…</string>
|
||||||
@ -20,6 +20,6 @@
|
|||||||
<string name="tests_failed">Incompatible device or OS.</string>
|
<string name="tests_failed">Incompatible device or OS.</string>
|
||||||
<string name="tests_btn_failed">Retest</string>
|
<string name="tests_btn_failed">Retest</string>
|
||||||
<string name="tests_passed">Integrity checks passed!</string>
|
<string name="tests_passed">Integrity checks passed!</string>
|
||||||
<string name="tests_btn_passed">Continue</string>
|
<string name="tests_btn_passed">Close</string>
|
||||||
<string name="nativeKDF">Use native key derivation</string>
|
<string name="nativeKDF">Use native key derivation</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -32,6 +32,7 @@ public class EmergencyActivity extends Activity {
|
|||||||
private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) );
|
private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) );
|
||||||
private static final int PASSWORD_NOTIFICATION = 0;
|
private static final int PASSWORD_NOTIFICATION = 0;
|
||||||
|
|
||||||
|
private final Preferences preferences = Preferences.get( this );
|
||||||
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
|
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
|
||||||
private final ValueChangedListener updateMasterKey = new ValueChangedListener() {
|
private final ValueChangedListener updateMasterKey = new ValueChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -136,23 +137,23 @@ public class EmergencyActivity extends Activity {
|
|||||||
rememberFullNameField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
rememberFullNameField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||||
getPreferences( MODE_PRIVATE ).edit().putBoolean( "rememberFullName", isChecked ).apply();
|
preferences.setRememberFullName( isChecked );
|
||||||
if (isChecked)
|
if (isChecked)
|
||||||
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", fullNameField.getText().toString() ).apply();
|
preferences.setFullName( fullNameField.getText().toString() );
|
||||||
else
|
else
|
||||||
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", "" ).apply();
|
preferences.setFullName( null );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
forgetPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
forgetPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||||
getPreferences( MODE_PRIVATE ).edit().putBoolean( "forgetPassword", isChecked ).apply();
|
preferences.setForgetPassword( isChecked );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
maskPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
maskPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||||
getPreferences( MODE_PRIVATE ).edit().putBoolean( "maskPassword", isChecked ).apply();
|
preferences.setMaskPassword( isChecked );
|
||||||
sitePasswordField.setTransformationMethod( isChecked? new PasswordTransformationMethod(): null );
|
sitePasswordField.setTransformationMethod( isChecked? new PasswordTransformationMethod(): null );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@ -162,13 +163,13 @@ public class EmergencyActivity extends Activity {
|
|||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
MasterKey.setAllowNativeByDefault( isNativeKDFEnabled() );
|
MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
|
||||||
|
|
||||||
fullNameField.setText( getPreferences( MODE_PRIVATE ).getString( "fullName", "" ) );
|
fullNameField.setText( preferences.getFullName() );
|
||||||
rememberFullNameField.setChecked( isRememberFullNameEnabled() );
|
rememberFullNameField.setChecked( preferences.isRememberFullName() );
|
||||||
forgetPasswordField.setChecked( isForgetPasswordEnabled() );
|
forgetPasswordField.setChecked( preferences.isForgetPassword() );
|
||||||
maskPasswordField.setChecked( isMaskPasswordEnabled() );
|
maskPasswordField.setChecked( preferences.isMaskPassword() );
|
||||||
sitePasswordField.setTransformationMethod( isMaskPasswordEnabled()? new PasswordTransformationMethod(): null );
|
sitePasswordField.setTransformationMethod( preferences.isMaskPassword()? new PasswordTransformationMethod(): null );
|
||||||
|
|
||||||
if (TextUtils.isEmpty( masterPasswordField.getText() ))
|
if (TextUtils.isEmpty( masterPasswordField.getText() ))
|
||||||
masterPasswordField.requestFocus();
|
masterPasswordField.requestFocus();
|
||||||
@ -178,7 +179,7 @@ public class EmergencyActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
if (isForgetPasswordEnabled()) {
|
if (preferences.isForgetPassword()) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
hc_userName = hc_masterPassword = 0;
|
hc_userName = hc_masterPassword = 0;
|
||||||
if (masterKeyFuture != null) {
|
if (masterKeyFuture != null) {
|
||||||
@ -197,22 +198,6 @@ public class EmergencyActivity extends Activity {
|
|||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNativeKDFEnabled() {
|
|
||||||
return getPreferences( MODE_PRIVATE ).getBoolean( "nativeKDF", MasterKey.isAllowNativeByDefault() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRememberFullNameEnabled() {
|
|
||||||
return getPreferences( MODE_PRIVATE ).getBoolean( "rememberFullName", false );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isForgetPasswordEnabled() {
|
|
||||||
return getPreferences( MODE_PRIVATE ).getBoolean( "forgetPassword", false );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMaskPasswordEnabled() {
|
|
||||||
return getPreferences( MODE_PRIVATE ).getBoolean( "maskPassword", false );
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void updateMasterKey() {
|
private synchronized void updateMasterKey() {
|
||||||
final String fullName = fullNameField.getText().toString();
|
final String fullName = fullNameField.getText().toString();
|
||||||
final char[] masterPassword = masterPasswordField.getText().toString().toCharArray();
|
final char[] masterPassword = masterPasswordField.getText().toString().toCharArray();
|
||||||
@ -228,8 +213,8 @@ public class EmergencyActivity extends Activity {
|
|||||||
hc_userName = fullName.hashCode();
|
hc_userName = fullName.hashCode();
|
||||||
hc_masterPassword = Arrays.hashCode( masterPassword );
|
hc_masterPassword = Arrays.hashCode( masterPassword );
|
||||||
|
|
||||||
if (isRememberFullNameEnabled())
|
if (preferences.isRememberFullName())
|
||||||
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", fullName ).apply();
|
preferences.setFullName( fullName );
|
||||||
|
|
||||||
if (masterKeyFuture != null)
|
if (masterKeyFuture != null)
|
||||||
masterKeyFuture.cancel( true );
|
masterKeyFuture.cancel( true );
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.lyndir.masterpassword;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lhunath, 2016-02-20
|
||||||
|
*/
|
||||||
|
public class Preferences {
|
||||||
|
|
||||||
|
private static final String PREF_TESTS_PASSED = "integrityTestsPassed";
|
||||||
|
private static final String PREF_NATIVE_KDF = "nativeKDF";
|
||||||
|
private static final String PREF_REMEMBER_FULL_NAME = "rememberFullName";
|
||||||
|
private static final String PREF_FORGET_PASSWORD = "forgetPassword";
|
||||||
|
private static final String PREF_MASK_PASSWORD = "maskPassword";
|
||||||
|
private static final String PREF_FULL_NAME = "fullName";
|
||||||
|
private static Preferences instance;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
@Nullable
|
||||||
|
private SharedPreferences prefs;
|
||||||
|
|
||||||
|
public static synchronized Preferences get(final Context context) {
|
||||||
|
if (instance == null)
|
||||||
|
instance = new Preferences( context );
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Preferences(Context context) {
|
||||||
|
this.context = context.getApplicationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private SharedPreferences prefs() {
|
||||||
|
if (prefs == null)
|
||||||
|
prefs = context.getSharedPreferences( getClass().getCanonicalName(), Context.MODE_PRIVATE );
|
||||||
|
|
||||||
|
return prefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setNativeKDFEnabled(boolean enabled) {
|
||||||
|
if (isAllowNativeKDF() == enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putBoolean( PREF_NATIVE_KDF, enabled ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAllowNativeKDF() {
|
||||||
|
return prefs().getBoolean( PREF_NATIVE_KDF, MasterKey.isAllowNativeByDefault() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setTestsPassed(final Set<String> testsPassed) {
|
||||||
|
if (Sets.symmetricDifference( getTestsPassed(), testsPassed ).isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putStringSet( PREF_TESTS_PASSED, testsPassed ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getTestsPassed() {
|
||||||
|
return prefs().getStringSet( PREF_TESTS_PASSED, ImmutableSet.<String>of() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setRememberFullName(boolean enabled) {
|
||||||
|
if (isRememberFullName() == enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putBoolean( PREF_REMEMBER_FULL_NAME, enabled ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRememberFullName() {
|
||||||
|
return prefs().getBoolean( PREF_REMEMBER_FULL_NAME, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setForgetPassword(boolean enabled) {
|
||||||
|
if (isForgetPassword() == enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putBoolean( PREF_FORGET_PASSWORD, enabled ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForgetPassword() {
|
||||||
|
return prefs().getBoolean( PREF_FORGET_PASSWORD, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setMaskPassword(boolean enabled) {
|
||||||
|
if (isMaskPassword() == enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putBoolean( PREF_MASK_PASSWORD, enabled ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMaskPassword() {
|
||||||
|
return prefs().getBoolean( PREF_MASK_PASSWORD, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setFullName(@Nullable String fullName) {
|
||||||
|
if (getFullName().equals( fullName ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
prefs().edit().putString( PREF_FULL_NAME, fullName ).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public String getFullName() {
|
||||||
|
return prefs().getString( PREF_FULL_NAME, "" );
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,6 @@ import com.google.common.base.*;
|
|||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.util.concurrent.*;
|
import com.google.common.util.concurrent.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -23,8 +22,8 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
|
|||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private static final Logger logger = Logger.get( TestActivity.class );
|
private static final Logger logger = Logger.get( TestActivity.class );
|
||||||
private static final String PREF_TESTS_PASSED = "integrityTestsPassed";
|
|
||||||
|
|
||||||
|
private final Preferences preferences = Preferences.get( this );
|
||||||
private final ListeningExecutorService backgroundExecutor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
|
private final ListeningExecutorService backgroundExecutor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
|
||||||
private final ListeningExecutorService mainExecutor = MoreExecutors.listeningDecorator( new MainThreadExecutor() );
|
private final ListeningExecutorService mainExecutor = MoreExecutors.listeningDecorator( new MainThreadExecutor() );
|
||||||
|
|
||||||
@ -63,8 +62,7 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
|
|||||||
nativeKDF.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
nativeKDF.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||||
getPreferences( MODE_PRIVATE ).edit().putBoolean( "nativeKDF", isChecked ).apply();
|
MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
|
||||||
MasterKey.setAllowNativeByDefault( isNativeKDFEnabled() );
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -96,21 +94,17 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
|
|||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
nativeKDF.setChecked( isNativeKDFEnabled() );
|
nativeKDF.setChecked( preferences.isAllowNativeKDF() );
|
||||||
|
|
||||||
if (testFuture == null)
|
if (testFuture == null)
|
||||||
startTestSuite();
|
startTestSuite();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNativeKDFEnabled() {
|
|
||||||
return getPreferences( MODE_PRIVATE ).getBoolean( "nativeKDF", MasterKey.isAllowNativeByDefault() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startTestSuite() {
|
private void startTestSuite() {
|
||||||
if (testFuture != null)
|
if (testFuture != null)
|
||||||
testFuture.cancel( true );
|
testFuture.cancel( true );
|
||||||
|
|
||||||
MasterKey.setAllowNativeByDefault( isNativeKDFEnabled() );
|
MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
|
||||||
|
|
||||||
setStatus( R.string.tests_testing, R.string.tests_btn_testing, null );
|
setStatus( R.string.tests_testing, R.string.tests_btn_testing, null );
|
||||||
Futures.addCallback( testFuture = backgroundExecutor.submit( testSuite ), new FutureCallback<Boolean>() {
|
Futures.addCallback( testFuture = backgroundExecutor.submit( testSuite ), new FutureCallback<Boolean>() {
|
||||||
@ -120,9 +114,8 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
|
|||||||
setStatus( R.string.tests_passed, R.string.tests_btn_passed, new Runnable() {
|
setStatus( R.string.tests_passed, R.string.tests_btn_passed, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
getPreferences( MODE_PRIVATE ).edit().putStringSet( PREF_TESTS_PASSED, testNames ).apply();
|
preferences.setTestsPassed( testNames );
|
||||||
finish();
|
finish();
|
||||||
EmergencyActivity.start( TestActivity.this );
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user