Some refactoring

* Wrap Settings in a class so we only have one location to edit defaults etc.
 * Move the authentication function to the BaseActivity
This commit is contained in:
Jakob Nixdorf 2017-08-17 11:08:54 +02:00
parent 8690eb1181
commit f616350aae
No known key found for this signature in database
GPG key ID: BE99BF86574A7DBC
7 changed files with 246 additions and 115 deletions

View file

@ -23,9 +23,7 @@
package org.shadowice.flocke.andotp.Activities; package org.shadowice.flocke.andotp.Activities;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.TextInputEditText; import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
@ -42,10 +40,10 @@ import android.widget.Toast;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import static org.shadowice.flocke.andotp.Utilities.Settings.AuthMethod;
public class AuthenticateActivity extends BaseActivity public class AuthenticateActivity extends BaseActivity
implements EditText.OnEditorActionListener { implements EditText.OnEditorActionListener {
private SharedPreferences settings;
private String password; private String password;
@Override @Override
@ -67,11 +65,10 @@ public class AuthenticateActivity extends BaseActivity
TextInputLayout passwordLayout = (TextInputLayout) v.findViewById(R.id.passwordLayout); TextInputLayout passwordLayout = (TextInputLayout) v.findViewById(R.id.passwordLayout);
TextInputEditText passwordInput = (TextInputEditText) v.findViewById(R.id.passwordEdit); TextInputEditText passwordInput = (TextInputEditText) v.findViewById(R.id.passwordEdit);
settings = PreferenceManager.getDefaultSharedPreferences(this); AuthMethod authMethod = settings.getAuthMethod();
String authMethod = settings.getString(getString(R.string.settings_key_auth), getString(R.string.settings_default_auth));
if (authMethod.equals("password")) { if (authMethod == AuthMethod.PASSWORD) {
password = settings.getString(getString(R.string.settings_key_auth_password), ""); password = settings.getAuthPassword();
if (password.isEmpty()) { if (password.isEmpty()) {
Toast.makeText(this, R.string.auth_toast_password_missing, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.auth_toast_password_missing, Toast.LENGTH_LONG).show();
@ -81,8 +78,8 @@ public class AuthenticateActivity extends BaseActivity
passwordLayout.setHint(getString(R.string.auth_hint_password)); passwordLayout.setHint(getString(R.string.auth_hint_password));
passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
} }
} else if (authMethod.equals("pin")) { } else if (authMethod == AuthMethod.PIN) {
password = settings.getString(getString(R.string.settings_key_auth_pin), ""); password = settings.getAuthPIN();
if (password.isEmpty()) { if (password.isEmpty()) {
Toast.makeText(this, R.string.auth_toast_pin_missing, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.auth_toast_pin_missing, Toast.LENGTH_LONG).show();

View file

@ -28,11 +28,9 @@ import android.app.PendingIntent;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender; import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
@ -65,30 +63,28 @@ import java.util.ArrayList;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
public class BackupActivity extends BaseActivity { public class BackupActivity extends BaseActivity {
private final static int INTENT_OPEN_DOCUMENT_PLAIN = 100; private final static int INTENT_OPEN_DOCUMENT_PLAIN = 200;
private final static int INTENT_SAVE_DOCUMENT_PLAIN = 101; private final static int INTENT_SAVE_DOCUMENT_PLAIN = 201;
private final static int INTENT_OPEN_DOCUMENT_CRYPT = 102; private final static int INTENT_OPEN_DOCUMENT_CRYPT = 202;
private final static int INTENT_SAVE_DOCUMENT_CRYPT = 103; private final static int INTENT_SAVE_DOCUMENT_CRYPT = 203;
private final static int INTENT_OPEN_DOCUMENT_PGP = 104; private final static int INTENT_OPEN_DOCUMENT_PGP = 204;
private final static int INTENT_SAVE_DOCUMENT_PGP = 105; private final static int INTENT_SAVE_DOCUMENT_PGP = 205;
private final static int INTENT_ENCRYPT_PGP = 106; private final static int INTENT_ENCRYPT_PGP = 206;
private final static int INTENT_DECRYPT_PGP = 107; private final static int INTENT_DECRYPT_PGP = 207;
private final static int PERMISSIONS_REQUEST_READ_IMPORT_PLAIN = 110; private final static int PERMISSIONS_REQUEST_READ_IMPORT_PLAIN = 210;
private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_PLAIN = 111; private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_PLAIN = 211;
private final static int PERMISSIONS_REQUEST_READ_IMPORT_CRYPT = 112; private final static int PERMISSIONS_REQUEST_READ_IMPORT_CRYPT = 212;
private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_CRYPT = 113; private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_CRYPT = 213;
private final static int PERMISSIONS_REQUEST_READ_IMPORT_PGP = 114; private final static int PERMISSIONS_REQUEST_READ_IMPORT_PGP = 214;
private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_PGP = 115; private final static int PERMISSIONS_REQUEST_WRITE_EXPORT_PGP = 215;
private static final String DEFAULT_BACKUP_FILENAME_PLAIN = "otp_accounts.json"; private static final String DEFAULT_BACKUP_FILENAME_PLAIN = "otp_accounts.json";
private static final String DEFAULT_BACKUP_FILENAME_CRYPT = "otp_accounts.json.aes"; private static final String DEFAULT_BACKUP_FILENAME_CRYPT = "otp_accounts.json.aes";
private static final String DEFAULT_BACKUP_FILENAME_PGP = "otp_accounts.json.gpg"; private static final String DEFAULT_BACKUP_FILENAME_PGP = "otp_accounts.json.gpg";
private static final String DEFAULT_BACKUP_MIMETYPE_PLAIN = "application/json"; private static final String DEFAULT_BACKUP_MIMETYPE_PLAIN = "application/json";
private static final String DEFAULT_BACKUP_MIMETYPE_CRYPT = "binary/aes"; private static final String DEFAULT_BACKUP_MIMETYPE_CRYPT = "binary/aes";
private static final String DEFAULT_BACKUP_MIMETYPE_PGP = "application/pgp-encrypted"; private static final String DEFAULT_BACKUP_MIMETYPE_PGP = "application/pgp-encrypted";
private SharedPreferences settings;
private OpenPgpServiceConnection pgpServiceConnection; private OpenPgpServiceConnection pgpServiceConnection;
private long pgpKeyId; private long pgpKeyId;
@ -112,8 +108,6 @@ public class BackupActivity extends BaseActivity {
stub.setLayoutResource(R.layout.content_backup); stub.setLayoutResource(R.layout.content_backup);
View v = stub.inflate(); View v = stub.inflate();
settings = PreferenceManager.getDefaultSharedPreferences(this);
// Plain-text // Plain-text
LinearLayout backupPlain = (LinearLayout) v.findViewById(R.id.button_backup_plain); LinearLayout backupPlain = (LinearLayout) v.findViewById(R.id.button_backup_plain);
@ -139,7 +133,7 @@ public class BackupActivity extends BaseActivity {
LinearLayout backupCrypt = (LinearLayout) v.findViewById(R.id.button_backup_crypt); LinearLayout backupCrypt = (LinearLayout) v.findViewById(R.id.button_backup_crypt);
LinearLayout restoreCrypt = (LinearLayout) v.findViewById(R.id.button_restore_crypt); LinearLayout restoreCrypt = (LinearLayout) v.findViewById(R.id.button_restore_crypt);
if (settings.getString(getString(R.string.settings_key_backup_password), "").isEmpty()) { if (settings.getBackupPassword().isEmpty()) {
cryptSetup.setVisibility(View.VISIBLE); cryptSetup.setVisibility(View.VISIBLE);
backupCrypt.setVisibility(View.GONE); backupCrypt.setVisibility(View.GONE);
restoreCrypt.setVisibility(View.GONE); restoreCrypt.setVisibility(View.GONE);
@ -165,8 +159,8 @@ public class BackupActivity extends BaseActivity {
// OpenPGP // OpenPGP
String PGPProvider = settings.getString(getString(R.string.settings_key_openpgp_provider), ""); String PGPProvider = settings.getOpenPGPProvider();
pgpKeyId = settings.getLong(getString(R.string.settings_key_openpgp_keyid), 0); pgpKeyId = settings.getOpenPGPKey();
TextView setupPGP = (TextView) v.findViewById(R.id.msg_openpgp_setup); TextView setupPGP = (TextView) v.findViewById(R.id.msg_openpgp_setup);
LinearLayout backupPGP = (LinearLayout) v.findViewById(R.id.button_backup_openpgp); LinearLayout backupPGP = (LinearLayout) v.findViewById(R.id.button_backup_openpgp);
@ -398,7 +392,7 @@ public class BackupActivity extends BaseActivity {
/* Encrypted backup functions */ /* Encrypted backup functions */
private void doRestoreCrypt(Uri uri) { private void doRestoreCrypt(Uri uri) {
String password = settings.getString(getString(R.string.settings_key_backup_password), ""); String password = settings.getBackupPassword();
if (! password.isEmpty()) { if (! password.isEmpty()) {
if (StorageHelper.isExternalStorageReadable()) { if (StorageHelper.isExternalStorageReadable()) {
@ -434,7 +428,7 @@ public class BackupActivity extends BaseActivity {
} }
private void doBackupCrypt(Uri uri) { private void doBackupCrypt(Uri uri) {
String password = settings.getString(getString(R.string.settings_key_backup_password), ""); String password = settings.getBackupPassword();
if (! password.isEmpty()) { if (! password.isEmpty()) {
if (StorageHelper.isExternalStorageWritable()) { if (StorageHelper.isExternalStorageWritable()) {
@ -531,7 +525,7 @@ public class BackupActivity extends BaseActivity {
if (encryptIntent == null) { if (encryptIntent == null) {
encryptIntent = new Intent(); encryptIntent = new Intent();
if (settings.getBoolean(getString(R.string.settings_key_openpgp_sign), false)) { if (settings.getOpenPGPSign()) {
encryptIntent.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT); encryptIntent.setAction(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
encryptIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, pgpKeyId); encryptIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, pgpKeyId);
} else { } else {
@ -573,7 +567,7 @@ public class BackupActivity extends BaseActivity {
doBackupEncrypted(file, outputStreamToString(os)); doBackupEncrypted(file, outputStreamToString(os));
} else if (requestCode == INTENT_DECRYPT_PGP) { } else if (requestCode == INTENT_DECRYPT_PGP) {
if (os != null) { if (os != null) {
if (settings.getBoolean(getString(R.string.settings_key_openpgp_verify), false)) { if (settings.getOpenPGPVerify()) {
OpenPgpSignatureResult sigResult = result.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE); OpenPgpSignatureResult sigResult = result.getParcelableExtra(OpenPgpApi.RESULT_SIGNATURE);
if (sigResult.getResult() == OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED) { if (sigResult.getResult() == OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED) {

View file

@ -22,18 +22,27 @@
package org.shadowice.flocke.andotp.Activities; package org.shadowice.flocke.andotp.Activities;
import android.content.SharedPreferences; import android.app.KeyguardManager;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Settings;
import static org.shadowice.flocke.andotp.Utilities.Settings.AuthMethod;
public class BaseActivity extends AppCompatActivity { public class BaseActivity extends AppCompatActivity {
private static final int INTENT_INTERNAL_AUTHENTICATE = 1;
public Settings settings;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); settings = new Settings(this);
String theme = sharedPref.getString(getString(R.string.settings_key_theme), getString(R.string.settings_default_theme));
String theme = settings.getTheme();
if (theme.equals("light")) { if (theme.equals("light")) {
setTheme(R.style.AppTheme_NoActionBar); setTheme(R.style.AppTheme_NoActionBar);
@ -43,4 +52,34 @@ public class BaseActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }
public void authenticate() {
AuthMethod authMethod = settings.getAuthMethod();
if (authMethod == AuthMethod.DEVICE) {
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && km.isKeyguardSecure()) {
Intent authIntent = km.createConfirmDeviceCredentialIntent(getString(R.string.dialog_title_auth), getString(R.string.dialog_msg_auth));
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
}
} else if (authMethod == AuthMethod.PASSWORD || authMethod == AuthMethod.PIN) {
Intent authIntent = new Intent(this, AuthenticateActivity.class);
startActivityForResult(authIntent, INTENT_INTERNAL_AUTHENTICATE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == INTENT_INTERNAL_AUTHENTICATE && resultCode != RESULT_OK) {
Toast.makeText(getBaseContext(), R.string.toast_auth_failed, Toast.LENGTH_LONG).show();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finish();
}
}
}
} }

View file

@ -25,14 +25,12 @@ package org.shadowice.flocke.andotp.Activities;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.constraint.ConstraintLayout; import android.support.constraint.ConstraintLayout;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
@ -62,8 +60,12 @@ import org.shadowice.flocke.andotp.View.ItemTouchHelper.SimpleItemTouchHelperCal
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.TokenCalculator; import org.shadowice.flocke.andotp.Utilities.TokenCalculator;
import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
public class MainActivity extends BaseActivity public class MainActivity extends BaseActivity
implements SharedPreferences.OnSharedPreferenceChangeListener { implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final int INTENT_INTERNAL_SETTINGS = 101;
private static final int INTENT_INTERNAL_BACKUP = 102;
private EntriesCardAdapter adapter; private EntriesCardAdapter adapter;
private FloatingActionMenu floatingActionMenu; private FloatingActionMenu floatingActionMenu;
@ -71,15 +73,9 @@ public class MainActivity extends BaseActivity
private MenuItem sortMenu; private MenuItem sortMenu;
private SimpleItemTouchHelperCallback touchHelperCallback; private SimpleItemTouchHelperCallback touchHelperCallback;
private SharedPreferences sharedPref;
private Handler handler; private Handler handler;
private Runnable handlerTask; private Runnable handlerTask;
private static final int INTENT_AUTHENTICATE = 1;
private static final int INTENT_INTERNAL_SETTINGS = 2;
private static final int INTENT_INTERNAL_BACKUP = 3;
// QR code scanning // QR code scanning
private void scanQRCode(){ private void scanQRCode(){
new IntentIntegrator(MainActivity.this) new IntentIntegrator(MainActivity.this)
@ -142,9 +138,7 @@ public class MainActivity extends BaseActivity
.setPositiveButton(R.string.button_warned, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.button_warned, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
sharedPref.edit() settings.setFirstTimeWarningShown(true);
.putBoolean(getString(R.string.settings_key_security_backup_warning), true)
.apply();
} }
}) })
.create() .create()
@ -152,35 +146,13 @@ public class MainActivity extends BaseActivity
} }
private void restoreSortMode(EntriesCardAdapter adapter) { private void restoreSortMode(EntriesCardAdapter adapter) {
if (sharedPref != null) { if (settings != null)
String modeStr = sharedPref.getString(getString(R.string.settings_key_sort_mode), EntriesCardAdapter.SortMode.UNSORTED.toString()); adapter.setSortMode(settings.getSortMode());
EntriesCardAdapter.SortMode mode = EntriesCardAdapter.SortMode.valueOf(modeStr);
adapter.setSortMode(mode);
}
} }
private void saveSortMode(EntriesCardAdapter.SortMode mode) { private void saveSortMode(SortMode mode) {
if (sharedPref != null) { if (settings != null)
sharedPref.edit() settings.setSortMode(mode);
.putString(getString(R.string.settings_key_sort_mode), mode.toString())
.apply();
}
}
public void authenticate() {
String authMethod = sharedPref.getString(getString(R.string.settings_key_auth), getString(R.string.settings_default_auth));
if (authMethod.equals("device")) {
KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && km.isKeyguardSecure()) {
Intent authIntent = km.createConfirmDeviceCredentialIntent(getString(R.string.dialog_title_auth), getString(R.string.dialog_msg_auth));
startActivityForResult(authIntent, INTENT_AUTHENTICATE);
}
} else if (authMethod.equals("password") || authMethod.equals("pin")) {
Intent authIntent = new Intent(this, AuthenticateActivity.class);
startActivityForResult(authIntent, INTENT_AUTHENTICATE);
}
} }
// Initialize the main application // Initialize the main application
@ -196,13 +168,12 @@ public class MainActivity extends BaseActivity
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false); PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
sharedPref = PreferenceManager.getDefaultSharedPreferences(this); settings.registerPreferenceChangeListener(this);
sharedPref.registerOnSharedPreferenceChangeListener(this);
if (savedInstanceState == null) if (savedInstanceState == null)
authenticate(); authenticate();
if (! sharedPref.getBoolean(getString(R.string.settings_key_security_backup_warning), false)) { if (! settings.getFirstTimeWarningShown()) {
showFirstTimeWarning(); showFirstTimeWarning();
} }
@ -250,7 +221,7 @@ public class MainActivity extends BaseActivity
ItemTouchHelper touchHelper = new ItemTouchHelper(touchHelperCallback); ItemTouchHelper touchHelper = new ItemTouchHelper(touchHelperCallback);
touchHelper.attachToRecyclerView(recList); touchHelper.attachToRecyclerView(recList);
float durationScale = Settings.Global.getFloat(this.getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 0); float durationScale = android.provider.Settings.Global.getFloat(this.getContentResolver(), android.provider.Settings.Global.ANIMATOR_DURATION_SCALE, 0);
final long animatorDuration = (long) (1000 / durationScale); final long animatorDuration = (long) (1000 / durationScale);
adapter.setCallback(new EntriesCardAdapter.Callback() { adapter.setCallback(new EntriesCardAdapter.Callback() {
@ -342,14 +313,6 @@ public class MainActivity extends BaseActivity
} else if (requestCode == INTENT_INTERNAL_BACKUP && resultCode == RESULT_OK) { } else if (requestCode == INTENT_INTERNAL_BACKUP && resultCode == RESULT_OK) {
if (intent.getBooleanExtra("reload", false)) if (intent.getBooleanExtra("reload", false))
adapter.loadEntries(); adapter.loadEntries();
} else if (requestCode == INTENT_AUTHENTICATE && resultCode != RESULT_OK) {
Toast.makeText(getBaseContext(), R.string.toast_auth_failed, Toast.LENGTH_LONG).show();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finish();
}
} }
} }
@ -361,12 +324,12 @@ public class MainActivity extends BaseActivity
sortMenu = menu.findItem(R.id.menu_sort); sortMenu = menu.findItem(R.id.menu_sort);
if (adapter != null) { if (adapter != null) {
EntriesCardAdapter.SortMode mode = adapter.getSortMode(); SortMode mode = adapter.getSortMode();
if (mode == EntriesCardAdapter.SortMode.UNSORTED) { if (mode == SortMode.UNSORTED) {
sortMenu.setIcon(R.drawable.ic_sort_inverted_white); sortMenu.setIcon(R.drawable.ic_sort_inverted_white);
menu.findItem(R.id.menu_sort_none).setChecked(true); menu.findItem(R.id.menu_sort_none).setChecked(true);
} else if (mode == EntriesCardAdapter.SortMode.LABEL) { } else if (mode == SortMode.LABEL) {
sortMenu.setIcon(R.drawable.ic_sort_inverted_label_white); sortMenu.setIcon(R.drawable.ic_sort_inverted_label_white);
menu.findItem(R.id.menu_sort_label).setChecked(true); menu.findItem(R.id.menu_sort_label).setChecked(true);
} }
@ -400,7 +363,7 @@ public class MainActivity extends BaseActivity
@Override @Override
public boolean onMenuItemActionCollapse(MenuItem item) { public boolean onMenuItemActionCollapse(MenuItem item) {
floatingActionMenu.show(); floatingActionMenu.show();
if (adapter == null || adapter.getSortMode() == EntriesCardAdapter.SortMode.UNSORTED) if (adapter == null || adapter.getSortMode() == SortMode.UNSORTED)
touchHelperCallback.setDragEnabled(true); touchHelperCallback.setDragEnabled(true);
if (sortMenu != null) if (sortMenu != null)
sortMenu.setVisible(true); sortMenu.setVisible(true);
@ -428,17 +391,17 @@ public class MainActivity extends BaseActivity
} else if (id == R.id.menu_sort_none) { } else if (id == R.id.menu_sort_none) {
item.setChecked(true); item.setChecked(true);
sortMenu.setIcon(R.drawable.ic_sort_inverted_white); sortMenu.setIcon(R.drawable.ic_sort_inverted_white);
saveSortMode(EntriesCardAdapter.SortMode.UNSORTED); saveSortMode(SortMode.UNSORTED);
if (adapter != null) { if (adapter != null) {
adapter.setSortMode(EntriesCardAdapter.SortMode.UNSORTED); adapter.setSortMode(SortMode.UNSORTED);
touchHelperCallback.setDragEnabled(true); touchHelperCallback.setDragEnabled(true);
} }
} else if (id == R.id.menu_sort_label) { } else if (id == R.id.menu_sort_label) {
item.setChecked(true); item.setChecked(true);
sortMenu.setIcon(R.drawable.ic_sort_inverted_label_white); sortMenu.setIcon(R.drawable.ic_sort_inverted_label_white);
saveSortMode(EntriesCardAdapter.SortMode.LABEL); saveSortMode(SortMode.LABEL);
if (adapter != null) { if (adapter != null) {
adapter.setSortMode(EntriesCardAdapter.SortMode.LABEL); adapter.setSortMode(SortMode.LABEL);
touchHelperCallback.setDragEnabled(false); touchHelperCallback.setDragEnabled(false);
} }
} }

View file

@ -42,7 +42,7 @@ import org.shadowice.flocke.andotp.R;
public class SettingsActivity extends BaseActivity public class SettingsActivity extends BaseActivity
implements SharedPreferences.OnSharedPreferenceChangeListener{ implements SharedPreferences.OnSharedPreferenceChangeListener{
SettingsFragment fragement; SettingsFragment fragment;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -57,10 +57,10 @@ public class SettingsActivity extends BaseActivity
ViewStub stub = (ViewStub) findViewById(R.id.container_stub); ViewStub stub = (ViewStub) findViewById(R.id.container_stub);
stub.inflate(); stub.inflate();
fragement = new SettingsFragment(); fragment = new SettingsFragment();
getFragmentManager().beginTransaction() getFragmentManager().beginTransaction()
.replace(R.id.container_content, fragement) .replace(R.id.container_content, fragment)
.commit(); .commit();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
@ -93,7 +93,7 @@ public class SettingsActivity extends BaseActivity
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (fragement.pgpKey.handleOnActivityResult(requestCode, resultCode, data)) { if (fragment.pgpKey.handleOnActivityResult(requestCode, resultCode, data)) {
// handled by OpenPgpKeyPreference // handled by OpenPgpKeyPreference
return; return;
} }

View file

@ -0,0 +1,141 @@
/*
* Copyright (C) 2017 Jakob Nixdorf
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.shadowice.flocke.andotp.Utilities;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.shadowice.flocke.andotp.R;
public class Settings {
private Context context;
private SharedPreferences settings;
public enum AuthMethod {
NONE, PASSWORD, PIN, DEVICE
}
public enum SortMode {
UNSORTED, LABEL
}
public Settings(Context context) {
this.context = context;
this.settings = PreferenceManager.getDefaultSharedPreferences(context);
}
private String getResString(int resId) {
return context.getString(resId);
}
private String getString(int keyId, int defaultId) {
return settings.getString(getResString(keyId), getResString(defaultId));
}
private String getString(int keyId, String defaultValue) {
return settings.getString(getResString(keyId), defaultValue);
}
private boolean getBoolean(int keyId, boolean defaultValue) {
return settings.getBoolean(getResString(keyId), defaultValue);
}
private long getLong(int keyId, long defaultValue) {
return settings.getLong(getResString(keyId), defaultValue);
}
private void setBoolean(int keyId, boolean value) {
settings.edit()
.putBoolean(getResString(keyId), value)
.apply();
}
private void setString(int keyId, String value) {
settings.edit()
.putString(getResString(keyId), value)
.apply();
}
public void registerPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) {
settings.registerOnSharedPreferenceChangeListener(listener);
}
public AuthMethod getAuthMethod() {
String authString = getString(R.string.settings_key_auth, R.string.settings_default_auth);
return AuthMethod.valueOf(authString.toUpperCase());
}
public String getAuthPassword() {
return getString(R.string.settings_key_auth_password, "");
}
public String getAuthPIN() {
return getString(R.string.settings_key_auth_pin, "");
}
public String getTheme() {
return getString(R.string.settings_key_theme, R.string.settings_default_theme);
}
public boolean getFirstTimeWarningShown() {
return getBoolean(R.string.settings_key_security_backup_warning, false);
}
public void setFirstTimeWarningShown(boolean value) {
setBoolean(R.string.settings_key_security_backup_warning, value);
}
public SortMode getSortMode() {
String modeStr = getString(R.string.settings_key_sort_mode, SortMode.UNSORTED.toString());
return SortMode.valueOf(modeStr);
}
public void setSortMode(SortMode value) {
setString(R.string.settings_key_sort_mode, value.toString());
}
public String getBackupPassword() {
return getString(R.string.settings_key_backup_password, "");
}
public String getOpenPGPProvider() {
return getString(R.string.settings_key_openpgp_provider, "");
}
public long getOpenPGPKey() {
return getLong(R.string.settings_key_openpgp_keyid, 0);
}
public boolean getOpenPGPSign() {
return getBoolean(R.string.settings_key_openpgp_sign, false);
}
public boolean getOpenPGPVerify() {
return getBoolean(R.string.settings_key_openpgp_verify, false);
}
}

View file

@ -47,17 +47,14 @@ import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter; import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder> public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
implements ItemTouchHelperAdapter, Filterable { implements ItemTouchHelperAdapter, Filterable {
public enum SortMode {
UNSORTED, LABEL
}
private Context context; private Context context;
private SharedPreferences sharedPrefs; private SharedPreferences sharedPrefs;
private EntryFilter filter; private EntryFilter filter;