Don't leave the PreferencesActivity when importing a database

This commit is contained in:
Alexander Bakker 2018-05-10 14:50:47 +02:00
parent 002045c7c7
commit 246d3d634e
3 changed files with 147 additions and 95 deletions

View file

@ -33,7 +33,8 @@ public class MasterKey implements Serializable {
} catch (NoSuchPaddingException
| NoSuchAlgorithmException
| InvalidAlgorithmParameterException
| InvalidKeyException | BadPaddingException
| InvalidKeyException
| BadPaddingException
| IllegalBlockSizeException e) {
throw new MasterKeyException(e);
}

View file

@ -20,12 +20,7 @@ import android.widget.Toast;
import com.getbase.floatingactionbutton.FloatingActionsMenu;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;
import me.impy.aegis.AegisApplication;
import me.impy.aegis.R;
@ -35,11 +30,8 @@ import me.impy.aegis.db.slots.SlotCollection;
import me.impy.aegis.db.DatabaseEntry;
import me.impy.aegis.db.DatabaseManager;
import me.impy.aegis.helpers.PermissionHelper;
import me.impy.aegis.importers.DatabaseImporter;
import me.impy.aegis.importers.DatabaseImporterException;
import me.impy.aegis.ui.views.KeyProfile;
import me.impy.aegis.ui.views.KeyProfileView;
import me.impy.aegis.util.ByteInputStream;
public class MainActivity extends AegisActivity implements KeyProfileView.Listener {
// activity request codes
@ -49,14 +41,12 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
private static final int CODE_ENTER_KEYINFO = 3;
private static final int CODE_DO_INTRO = 4;
private static final int CODE_DECRYPT = 5;
private static final int CODE_IMPORT = 6;
private static final int CODE_PREFERENCES = 7;
private static final int CODE_SLOTS = 8;
private static final int CODE_PREFERENCES = 6;
private static final int CODE_SLOTS = 7;
// permission request codes
private static final int CODE_PERM_EXPORT = 0;
private static final int CODE_PERM_IMPORT = 1;
private static final int CODE_PERM_CAMERA = 2;
private static final int CODE_PERM_CAMERA = 1;
private AegisApplication _app;
private DatabaseManager _db;
@ -187,14 +177,12 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
case CODE_DECRYPT:
onDecryptResult(resultCode, data);
break;
case CODE_IMPORT:
onImportResult(resultCode, data);
break;
case CODE_PREFERENCES:
onPreferencesResult(resultCode, data);
break;
case CODE_SLOTS:
onSlotManagerResult(resultCode, data);
break;
}
}
@ -209,9 +197,6 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
case CODE_PERM_EXPORT:
onExport();
break;
case CODE_PERM_IMPORT:
onImport();
break;
case CODE_PERM_CAMERA:
onScanKeyInfo();
break;
@ -230,6 +215,12 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
private void onPreferencesResult(int resultCode, Intent data) {
// refresh the entire key profile list if needed
if (data.getBooleanExtra("needsReload", false)) {
_keyProfileView.clearKeys();
for (DatabaseEntry entry : _db.getKeys()) {
_keyProfileView.addKey(new KeyProfile(entry));
}
}
if (data.getBooleanExtra("needsRefresh", false)) {
boolean showIssuer = _app.getPreferences().getBoolean("pref_issuer", false);
_keyProfileView.setShowIssuer(showIssuer);
@ -238,11 +229,6 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
// perform any pending actions
int action = data.getIntExtra("action", -1);
switch (action) {
case PreferencesActivity.ACTION_IMPORT:
if (PermissionHelper.request(this, CODE_PERM_IMPORT, Manifest.permission.READ_EXTERNAL_STORAGE)) {
onImport();
}
break;
case PreferencesActivity.ACTION_EXPORT:
onExport();
break;
@ -296,71 +282,6 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
builder.show();
}
private void onImport() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, CODE_IMPORT);
}
private void onImportResult(int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
InputStream fileStream = null;
try {
try {
fileStream = getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
Toast.makeText(this, "Error: File not found", Toast.LENGTH_SHORT).show();
return;
}
ByteInputStream stream;
try {
int read;
byte[] buf = new byte[4096];
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while ((read = fileStream.read(buf, 0, buf.length)) != -1) {
outStream.write(buf, 0, read);
}
stream = new ByteInputStream(outStream.toByteArray());
} catch (IOException e) {
Toast.makeText(this, "An error occurred while trying to read the file", Toast.LENGTH_SHORT).show();
return;
}
List<DatabaseEntry> entries = null;
for (DatabaseImporter converter : DatabaseImporter.create(stream)) {
try {
entries = converter.convert();
break;
} catch (DatabaseImporterException e) {
stream.reset();
}
}
if (entries == null) {
Toast.makeText(this, "An error occurred while trying to parse the file", Toast.LENGTH_SHORT).show();
return;
}
for (DatabaseEntry entry : entries) {
addKey(new KeyProfile(entry));
}
} finally {
if (fileStream != null) {
try {
fileStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
saveDatabase();
}
private void startEditProfileActivity(int requestCode, KeyProfile profile, boolean isNew) {
Intent intent = new Intent(this, EditProfileActivity.class);
if (profile != null) {

View file

@ -1,5 +1,6 @@
package me.impy.aegis.ui;
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.preference.EditTextPreference;
@ -7,12 +8,34 @@ import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import me.impy.aegis.AegisApplication;
import me.impy.aegis.R;
import me.impy.aegis.db.DatabaseEntry;
import me.impy.aegis.db.DatabaseManager;
import me.impy.aegis.db.DatabaseManagerException;
import me.impy.aegis.helpers.PermissionHelper;
import me.impy.aegis.importers.DatabaseImporter;
import me.impy.aegis.importers.DatabaseImporterException;
import me.impy.aegis.ui.views.KeyProfile;
import me.impy.aegis.util.ByteInputStream;
public class PreferencesActivity extends AegisActivity {
public static final int ACTION_IMPORT = 0;
public static final int ACTION_EXPORT = 1;
public static final int ACTION_SLOTS = 2;
// activity request codes
private static final int CODE_IMPORT = 0;
// permission request codes
private static final int CODE_PERM_IMPORT = 0;
// action codes
public static final int ACTION_EXPORT = 0;
public static final int ACTION_SLOTS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -34,6 +57,8 @@ public class PreferencesActivity extends AegisActivity {
public static class PreferencesFragment extends PreferenceFragment {
private Intent _result = new Intent();
private AegisApplication _app;
private DatabaseManager _db;
private void setResult() {
getActivity().setResult(RESULT_OK, _result);
@ -48,6 +73,8 @@ public class PreferencesActivity extends AegisActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
_app = (AegisApplication) getActivity().getApplication();
_db = _app.getDatabaseManager();
// set the result intent in advance
setResult();
@ -65,8 +92,9 @@ public class PreferencesActivity extends AegisActivity {
exportPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
_result.putExtra("action", ACTION_IMPORT);
finish();
if (PermissionHelper.request(getActivity(), CODE_PERM_IMPORT, Manifest.permission.READ_EXTERNAL_STORAGE)) {
onImport();
}
return true;
}
});
@ -111,5 +139,107 @@ public class PreferencesActivity extends AegisActivity {
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (!PermissionHelper.checkResults(grantResults)) {
Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
return;
}
switch (requestCode) {
case CODE_PERM_IMPORT:
onImport();
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
return;
}
switch (requestCode) {
case CODE_IMPORT:
onImportResult(resultCode, data);
break;
}
}
private void onImport() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, CODE_IMPORT);
}
private void onImportResult(int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
InputStream fileStream = null;
List<DatabaseEntry> entries = null;
try {
try {
fileStream = getActivity().getContentResolver().openInputStream(data.getData());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), "Error: File not found", Toast.LENGTH_SHORT).show();
return;
}
ByteInputStream stream;
try {
int read;
byte[] buf = new byte[4096];
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while ((read = fileStream.read(buf, 0, buf.length)) != -1) {
outStream.write(buf, 0, read);
}
stream = new ByteInputStream(outStream.toByteArray());
} catch (IOException e) {
Toast.makeText(getActivity(), "An error occurred while trying to read the file", Toast.LENGTH_SHORT).show();
return;
}
for (DatabaseImporter converter : DatabaseImporter.create(stream)) {
try {
entries = converter.convert();
break;
} catch (DatabaseImporterException e) {
stream.reset();
}
}
} finally {
if (fileStream != null) {
try {
fileStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (entries == null) {
Toast.makeText(getActivity(), "An error occurred while trying to parse the file", Toast.LENGTH_SHORT).show();
return;
}
for (DatabaseEntry entry : entries) {
_db.addKey(entry);
}
try {
_db.save();
} catch (DatabaseManagerException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "An error occurred while trying to save the database", Toast.LENGTH_LONG).show();
return;
}
_result.putExtra("needsReload", true);
Toast.makeText(getActivity(), String.format(Locale.getDefault(), "Imported %d entries", entries.size()), Toast.LENGTH_SHORT).show();
}
}
}