mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge branch 'feature/RefactorProgress' into develop #98
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
KeepassDX (2.5.0.0beta10)
|
||||
* Upgrade translations
|
||||
* Fix classic dark theme
|
||||
* Add Material Icon Pack to the Free version
|
||||
* Fix bugs
|
||||
|
||||
KeepassDX (2.5.0.0beta9)
|
||||
* Education Screens to learn how to use the app
|
||||
* New designs
|
||||
|
||||
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.kunzisoft.keepass"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 27
|
||||
versionCode = 9
|
||||
versionName = "2.5.0.0beta9"
|
||||
versionCode = 10
|
||||
versionName = "2.5.0.0beta10"
|
||||
multiDexEnabled true
|
||||
|
||||
testApplicationId = "com.kunzisoft.keepass.tests"
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.kunzisoft.keepass.database.PwDatabaseV3;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwEntryV3;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
import com.kunzisoft.keepass.database.edit.DeleteGroup;
|
||||
import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.search.SearchDbHelper;
|
||||
|
||||
public class DeleteEntry extends AndroidTestCase {
|
||||
@@ -60,7 +60,7 @@ public class DeleteEntry extends AndroidTestCase {
|
||||
assertNotNull("Could not find group1", group1);
|
||||
|
||||
// Delete the group
|
||||
DeleteGroup task = new DeleteGroup(null, db, group1, null, true);
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(null, db, group1, null, true);
|
||||
task.run();
|
||||
|
||||
// Verify the entries were deleted
|
||||
|
||||
@@ -49,16 +49,17 @@ import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
import com.kunzisoft.keepass.database.PwGroupId;
|
||||
import com.kunzisoft.keepass.database.PwIconStandard;
|
||||
import com.kunzisoft.keepass.database.edit.AddEntry;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.RunnableOnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.UpdateEntry;
|
||||
import com.kunzisoft.keepass.database.action.AddEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.action.RunnableOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.UpdateEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.security.ProtectedString;
|
||||
import com.kunzisoft.keepass.dialogs.GeneratePasswordDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
|
||||
import com.kunzisoft.keepass.icons.IconPackChooser;
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
import com.kunzisoft.keepass.utils.MenuUtil;
|
||||
import com.kunzisoft.keepass.utils.Types;
|
||||
import com.kunzisoft.keepass.utils.Util;
|
||||
@@ -249,16 +250,21 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
}
|
||||
mCallbackNewEntry = populateNewEntry();
|
||||
|
||||
OnFinish onFinish = new AfterSave();
|
||||
// Open a progress dialog and save entry
|
||||
OnFinishRunnable onFinish = new AfterSave();
|
||||
EntryEditActivity act = EntryEditActivity.this;
|
||||
RunnableOnFinish task;
|
||||
if ( mIsNew ) {
|
||||
task = new AddEntry(act, App.getDB(), mCallbackNewEntry, onFinish);
|
||||
task = new AddEntryRunnable(act, App.getDB(), mCallbackNewEntry, onFinish);
|
||||
} else {
|
||||
task = new UpdateEntry(act, App.getDB(), mEntry, mCallbackNewEntry, onFinish);
|
||||
task = new UpdateEntryRunnable(act, App.getDB(), mEntry, mCallbackNewEntry, onFinish);
|
||||
}
|
||||
ProgressTask pt = new ProgressTask(act, task, R.string.saving_database);
|
||||
pt.run();
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager())
|
||||
));
|
||||
new Thread(task).start();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -554,7 +560,7 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
}
|
||||
}
|
||||
|
||||
private final class AfterSave extends OnFinish {
|
||||
private final class AfterSave extends OnFinishRunnable {
|
||||
|
||||
AfterSave() {
|
||||
super(new Handler());
|
||||
@@ -562,11 +568,15 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
finish();
|
||||
} else {
|
||||
displayMessage(EntryEditActivity.this);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if ( mSuccess ) {
|
||||
finish();
|
||||
} else {
|
||||
displayMessage(EntryEditActivity.this);
|
||||
}
|
||||
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ import com.kunzisoft.keepass.database.PwIcon;
|
||||
import com.kunzisoft.keepass.database.PwIconStandard;
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.SortNodeEnum;
|
||||
import com.kunzisoft.keepass.database.edit.AddGroup;
|
||||
import com.kunzisoft.keepass.database.edit.DeleteEntry;
|
||||
import com.kunzisoft.keepass.database.edit.DeleteGroup;
|
||||
import com.kunzisoft.keepass.database.edit.UpdateGroup;
|
||||
import com.kunzisoft.keepass.database.action.AddGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.DeleteEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.UpdateGroupRunnable;
|
||||
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
|
||||
@@ -68,7 +68,8 @@ import com.kunzisoft.keepass.dialogs.ReadOnlyDialog;
|
||||
import com.kunzisoft.keepass.icons.IconPackChooser;
|
||||
import com.kunzisoft.keepass.search.SearchResultsActivity;
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
import com.kunzisoft.keepass.view.AddNodeButtonView;
|
||||
|
||||
public class GroupActivity extends ListNodesActivity
|
||||
@@ -435,19 +436,27 @@ public class GroupActivity extends ListNodesActivity
|
||||
|
||||
private void deleteEntry(PwEntry entry) {
|
||||
Handler handler = new Handler();
|
||||
DeleteEntry task = new DeleteEntry(this, App.getDB(), entry,
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(this, App.getDB(), entry,
|
||||
new AfterDeleteNode(handler, entry));
|
||||
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database);
|
||||
pt.run();
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager())
|
||||
));
|
||||
new Thread(task).start();
|
||||
}
|
||||
|
||||
private void deleteGroup(PwGroup group) {
|
||||
//TODO Verify trash recycle bin
|
||||
Handler handler = new Handler();
|
||||
DeleteGroup task = new DeleteGroup(this, App.getDB(), group,
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(this, App.getDB(), group,
|
||||
new AfterDeleteNode(handler, group));
|
||||
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database);
|
||||
pt.run();
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager())
|
||||
));
|
||||
new Thread(task).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -548,16 +557,21 @@ public class GroupActivity extends ListNodesActivity
|
||||
newGroup.setName(name);
|
||||
try {
|
||||
iconStandard = (PwIconStandard) icon;
|
||||
} catch (Exception e) {} // TODO custom icon
|
||||
} catch (Exception ignored) {} // TODO custom icon
|
||||
newGroup.setIcon(iconStandard);
|
||||
|
||||
new ProgressTask(this,
|
||||
new AddGroup(this,
|
||||
App.getDB(),
|
||||
newGroup,
|
||||
new AfterAddNode(new Handler())),
|
||||
R.string.saving_database)
|
||||
.run();
|
||||
// If group created save it in the database
|
||||
AddGroupRunnable addGroupRunnable = new AddGroupRunnable(this,
|
||||
App.getDB(),
|
||||
newGroup,
|
||||
new AfterAddNode(new Handler()));
|
||||
addGroupRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager())
|
||||
));
|
||||
new Thread(addGroupRunnable).start();
|
||||
|
||||
break;
|
||||
case UPDATE:
|
||||
// If update add new elements
|
||||
@@ -566,20 +580,23 @@ public class GroupActivity extends ListNodesActivity
|
||||
updateGroup.setName(name);
|
||||
try {
|
||||
iconStandard = (PwIconStandard) icon;
|
||||
} catch (Exception e) {} // TODO custom icon
|
||||
} catch (Exception ignored) {} // TODO custom icon
|
||||
updateGroup.setIcon(iconStandard);
|
||||
|
||||
mAdapter.removeNode(oldGroupToUpdate);
|
||||
// If group update
|
||||
new ProgressTask(this,
|
||||
new UpdateGroup(this,
|
||||
App.getDB(),
|
||||
oldGroupToUpdate,
|
||||
updateGroup,
|
||||
new AfterUpdateNode(new Handler())),
|
||||
R.string.saving_database)
|
||||
.run();
|
||||
|
||||
// If group updated save it in the database
|
||||
UpdateGroupRunnable updateGroupRunnable = new UpdateGroupRunnable(this,
|
||||
App.getDB(),
|
||||
oldGroupToUpdate,
|
||||
updateGroup,
|
||||
new AfterUpdateNode(new Handler()));
|
||||
updateGroupRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager())
|
||||
));
|
||||
new Thread(updateGroupRunnable).start();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -49,12 +49,13 @@ import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.SortNodeEnum;
|
||||
import com.kunzisoft.keepass.database.edit.AfterActionNodeOnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.action.AfterActionNodeOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.SortDialogFragment;
|
||||
import com.kunzisoft.keepass.password.AssignPasswordHelper;
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UIToastTask;
|
||||
import com.kunzisoft.keepass.utils.MenuUtil;
|
||||
|
||||
@@ -307,11 +308,16 @@ public abstract class ListNodesActivity extends LockingActivity
|
||||
|
||||
public void run(PwNode oldNode, PwNode newNode) {
|
||||
super.run();
|
||||
if (mSuccess) {
|
||||
mAdapter.addNode(newNode);
|
||||
} else {
|
||||
displayMessage(ListNodesActivity.this);
|
||||
}
|
||||
|
||||
runOnUiThread(() -> {
|
||||
if (mSuccess) {
|
||||
mAdapter.addNode(newNode);
|
||||
} else {
|
||||
displayMessage(ListNodesActivity.this);
|
||||
}
|
||||
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,15 +328,20 @@ public abstract class ListNodesActivity extends LockingActivity
|
||||
|
||||
public void run(PwNode oldNode, PwNode newNode) {
|
||||
super.run();
|
||||
if (mSuccess) {
|
||||
mAdapter.updateNode(oldNode, newNode);
|
||||
} else {
|
||||
displayMessage(ListNodesActivity.this);
|
||||
}
|
||||
|
||||
runOnUiThread(() -> {
|
||||
if (mSuccess) {
|
||||
mAdapter.updateNode(oldNode, newNode);
|
||||
} else {
|
||||
displayMessage(ListNodesActivity.this);
|
||||
}
|
||||
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class AfterDeleteNode extends OnFinish {
|
||||
class AfterDeleteNode extends OnFinishRunnable {
|
||||
private PwNode pwNode;
|
||||
|
||||
AfterDeleteNode(Handler handler, PwNode pwNode) {
|
||||
@@ -340,27 +351,33 @@ public abstract class ListNodesActivity extends LockingActivity
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess) {
|
||||
mAdapter.removeNode(pwNode);
|
||||
PwGroup parent = pwNode.getParent();
|
||||
Database db = App.getDB();
|
||||
PwDatabase database = db.getPwDatabase();
|
||||
if (db.isRecycleBinAvailable() &&
|
||||
db.isRecycleBinEnabled()) {
|
||||
PwGroup recycleBin = database.getRecycleBin();
|
||||
// Add trash if it doesn't exists
|
||||
if (parent.equals(recycleBin)
|
||||
&& mCurrentGroup != null
|
||||
&& mCurrentGroup.getParent() == null
|
||||
&& !mCurrentGroup.equals(recycleBin)) {
|
||||
mAdapter.addNode(parent);
|
||||
super.run();
|
||||
|
||||
runOnUiThread(() -> {
|
||||
if ( mSuccess) {
|
||||
mAdapter.removeNode(pwNode);
|
||||
PwGroup parent = pwNode.getParent();
|
||||
Database db = App.getDB();
|
||||
PwDatabase database = db.getPwDatabase();
|
||||
if (db.isRecycleBinAvailable() &&
|
||||
db.isRecycleBinEnabled()) {
|
||||
PwGroup recycleBin = database.getRecycleBin();
|
||||
// Add trash if it doesn't exists
|
||||
if (parent.equals(recycleBin)
|
||||
&& mCurrentGroup != null
|
||||
&& mCurrentGroup.getParent() == null
|
||||
&& !mCurrentGroup.equals(recycleBin)) {
|
||||
mAdapter.addNode(parent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mHandler.post(new UIToastTask(ListNodesActivity.this, "Unrecoverable error: " + mMessage));
|
||||
App.setShutdown();
|
||||
finish();
|
||||
}
|
||||
} else {
|
||||
mHandler.post(new UIToastTask(ListNodesActivity.this, "Unrecoverable error: " + mMessage));
|
||||
App.setShutdown();
|
||||
finish();
|
||||
}
|
||||
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.kunzisoft.keepass.database.load.ImporterFactory;
|
||||
import com.kunzisoft.keepass.database.save.PwDbOutput;
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory;
|
||||
import com.kunzisoft.keepass.search.SearchDbHelper;
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
import com.kunzisoft.keepass.utils.UriUtil;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@@ -99,19 +99,11 @@ public class Database {
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, InputStream is, String password, InputStream keyInputStream) throws IOException, InvalidDBException {
|
||||
loadData(ctx, is, password, keyInputStream, new UpdateStatus(), !Importer.DEBUG);
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, Uri uri, String password, Uri keyfile) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
loadData(ctx, uri, password, keyfile, new UpdateStatus(), !Importer.DEBUG);
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
public void loadData(Context ctx, Uri uri, String password, Uri keyfile, ProgressTaskUpdater status) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
loadData(ctx, uri, password, keyfile, status, !Importer.DEBUG);
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
public void loadData(Context ctx, Uri uri, String password, Uri keyfile, ProgressTaskUpdater status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
mUri = uri;
|
||||
readOnly = false;
|
||||
if (uri.getScheme().equals("file")) {
|
||||
@@ -138,7 +130,7 @@ public class Database {
|
||||
}
|
||||
|
||||
|
||||
private void passUrisAsInputStreams(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status, boolean debug, long roundsFix) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
private void passUrisAsInputStreams(Context ctx, Uri uri, String password, Uri keyfile, ProgressTaskUpdater status, boolean debug, long roundsFix) throws IOException, FileNotFoundException, InvalidDBException {
|
||||
InputStream is, kfIs;
|
||||
try {
|
||||
is = UriUtil.getUriInputStream(ctx, uri);
|
||||
@@ -157,14 +149,10 @@ public class Database {
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, InputStream is, String password, InputStream kfIs, boolean debug) throws IOException, InvalidDBException {
|
||||
loadData(ctx, is, password, kfIs, new UpdateStatus(), debug);
|
||||
loadData(ctx, is, password, kfIs, null, debug, 0);
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, InputStream is, String password, InputStream kfIs, UpdateStatus status, boolean debug) throws IOException, InvalidDBException {
|
||||
loadData(ctx, is, password, kfIs, status, debug, 0);
|
||||
}
|
||||
|
||||
public void loadData(Context ctx, InputStream is, String password, InputStream kfIs, UpdateStatus status, boolean debug, long roundsFix) throws IOException, InvalidDBException {
|
||||
private void loadData(Context ctx, InputStream is, String password, InputStream kfIs, ProgressTaskUpdater progressTaskUpdater, boolean debug, long roundsFix) throws IOException, InvalidDBException {
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
|
||||
if ( ! bis.markSupported() ) {
|
||||
@@ -178,7 +166,7 @@ public class Database {
|
||||
|
||||
bis.reset(); // Return to the start
|
||||
|
||||
pm = imp.openDatabase(bis, password, kfIs, status, roundsFix);
|
||||
pm = imp.openDatabase(bis, password, kfIs, progressTaskUpdater, roundsFix);
|
||||
if ( pm != null ) {
|
||||
try {
|
||||
switch (pm.getVersion()) {
|
||||
@@ -222,19 +210,23 @@ public class Database {
|
||||
saveData(ctx, mUri);
|
||||
}
|
||||
|
||||
public void saveData(Context ctx, Uri uri) throws IOException, PwDbOutputException {
|
||||
private void saveData(Context ctx, Uri uri) throws IOException, PwDbOutputException {
|
||||
if (uri.getScheme().equals("file")) {
|
||||
String filename = uri.getPath();
|
||||
File tempFile = new File(filename + ".tmp");
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
//BufferedOutputStream bos = new BufferedOutputStream(fos);
|
||||
|
||||
//PwDbV3Output pmo = new PwDbV3Output(pm, bos, App.getCalendar());
|
||||
PwDbOutput pmo = PwDbOutput.getInstance(pm, fos);
|
||||
pmo.output();
|
||||
//bos.flush();
|
||||
//bos.close();
|
||||
fos.close();
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(tempFile);
|
||||
PwDbOutput pmo = PwDbOutput.getInstance(pm, fos);
|
||||
if (pmo != null)
|
||||
pmo.output();
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Failed to store database.");
|
||||
} finally {
|
||||
if (fos != null)
|
||||
fos.close();
|
||||
}
|
||||
|
||||
// Force data to disk before continuing
|
||||
try {
|
||||
@@ -250,16 +242,18 @@ public class Database {
|
||||
}
|
||||
}
|
||||
else {
|
||||
OutputStream os;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = ctx.getContentResolver().openOutputStream(uri);
|
||||
PwDbOutput pmo = PwDbOutput.getInstance(pm, os);
|
||||
if (pmo != null)
|
||||
pmo.output();
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Failed to store database.");
|
||||
} finally {
|
||||
if (os != null)
|
||||
os.close();
|
||||
}
|
||||
|
||||
PwDbOutput pmo = PwDbOutput.getInstance(pm, os);
|
||||
pmo.output();
|
||||
os.close();
|
||||
}
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
@@ -100,25 +100,6 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
|
||||
return finalKey;
|
||||
}
|
||||
|
||||
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, long numRounds) throws IOException {
|
||||
|
||||
// Write checksum Checksum
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException("SHA-256 not implemented here.");
|
||||
}
|
||||
NullOutputStream nos = new NullOutputStream();
|
||||
DigestOutputStream dos = new DigestOutputStream(nos, md);
|
||||
|
||||
byte[] transformedMasterKey = transformMasterKey(masterSeed2, masterKey, numRounds);
|
||||
dos.write(masterSeed);
|
||||
dos.write(transformedMasterKey);
|
||||
|
||||
finalKey = md.digest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the master key a few times to make brute-force key-search harder
|
||||
* @throws IOException
|
||||
|
||||
@@ -47,9 +47,13 @@ package com.kunzisoft.keepass.database;
|
||||
|
||||
import com.kunzisoft.keepass.crypto.keyDerivation.AesKdf;
|
||||
import com.kunzisoft.keepass.database.exception.InvalidKeyFileException;
|
||||
import com.kunzisoft.keepass.stream.NullOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
@@ -250,6 +254,25 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
|
||||
}
|
||||
}
|
||||
|
||||
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, long numRounds) throws IOException {
|
||||
|
||||
// Write checksum Checksum
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException("SHA-256 not implemented here.");
|
||||
}
|
||||
NullOutputStream nos = new NullOutputStream();
|
||||
DigestOutputStream dos = new DigestOutputStream(nos, md);
|
||||
|
||||
byte[] transformedMasterKey = transformMasterKey(masterSeed2, masterKey, numRounds);
|
||||
dos.write(masterSeed);
|
||||
dos.write(transformedMasterKey);
|
||||
|
||||
finalKey = md.digest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPasswordEncoding() {
|
||||
return "ISO-8859-1";
|
||||
|
||||
@@ -362,28 +362,6 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
|
||||
return md.digest(fKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, long numRounds) throws IOException {
|
||||
|
||||
byte[] transformedMasterKey = transformMasterKey(masterSeed2, masterKey, numRounds);
|
||||
|
||||
|
||||
byte[] cmpKey = new byte[65];
|
||||
System.arraycopy(masterSeed, 0, cmpKey, 0, 32);
|
||||
System.arraycopy(transformedMasterKey, 0, cmpKey, 32, 32);
|
||||
finalKey = CryptoUtil.resizeKey(cmpKey, 0, 64, dataEngine.keyLength());
|
||||
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA-512");
|
||||
cmpKey[64] = 1;
|
||||
hmacKey = md.digest(cmpKey);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IOException("No SHA-512 implementation");
|
||||
} finally {
|
||||
Arrays.fill(cmpKey, (byte)0);
|
||||
}
|
||||
}
|
||||
public void makeFinalKey(byte[] masterSeed, KdfParameters kdfP) throws IOException {
|
||||
makeFinalKey(masterSeed, kdfP, 0);
|
||||
}
|
||||
|
||||
@@ -17,25 +17,25 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
|
||||
public class AddEntry extends RunnableOnFinish {
|
||||
public class AddEntryRunnable extends RunnableOnFinish {
|
||||
|
||||
protected Database mDb;
|
||||
private PwEntry mEntry;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
|
||||
public AddEntry(Context ctx, Database db, PwEntry entry, OnFinish finish) {
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
|
||||
this(ctx, db, entry, finish, false);
|
||||
}
|
||||
|
||||
public AddEntry(Context ctx, Database db, PwEntry entry, OnFinish finish, boolean dontSave) {
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -51,13 +51,13 @@ public class AddEntry extends RunnableOnFinish {
|
||||
mDb.addEntryTo(mEntry, mEntry.getParent());
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterAdd extends OnFinish {
|
||||
private class AfterAdd extends OnFinishRunnable {
|
||||
|
||||
AfterAdd(OnFinish finish) {
|
||||
AfterAdd(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@@ -17,26 +17,26 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class AddGroup extends RunnableOnFinish {
|
||||
public class AddGroupRunnable extends RunnableOnFinish {
|
||||
|
||||
protected Database mDb;
|
||||
private PwGroup mNewGroup;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
|
||||
public AddGroup(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode) {
|
||||
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode) {
|
||||
this(ctx, db, newGroup, afterAddNode, false);
|
||||
}
|
||||
|
||||
public AddGroup(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode,
|
||||
boolean dontSave) {
|
||||
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode,
|
||||
boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -52,13 +52,13 @@ public class AddGroup extends RunnableOnFinish {
|
||||
mDb.addGroupTo(mNewGroup, mNewGroup.getParent());
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterAdd extends OnFinish {
|
||||
private class AfterAdd extends OnFinishRunnable {
|
||||
|
||||
AfterAdd(OnFinish finish) {
|
||||
AfterAdd(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
|
||||
public abstract class AfterActionNodeOnFinish extends OnFinish {
|
||||
public abstract class AfterActionNodeOnFinish extends OnFinishRunnable {
|
||||
public AfterActionNodeOnFinish(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
@@ -17,22 +17,20 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwDatabase;
|
||||
import com.kunzisoft.keepass.database.exception.InvalidKeyFileException;
|
||||
import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper;
|
||||
import com.kunzisoft.keepass.utils.UriUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class SetPassword extends RunnableOnFinish {
|
||||
public class AssignPasswordInDBRunnable extends RunnableOnFinish {
|
||||
|
||||
private String mPassword;
|
||||
private Uri mKeyfile;
|
||||
@@ -40,12 +38,12 @@ public class SetPassword extends RunnableOnFinish {
|
||||
private boolean mDontSave;
|
||||
private Context ctx;
|
||||
|
||||
public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish) {
|
||||
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish) {
|
||||
this(ctx, db, password, keyfile, finish, false);
|
||||
|
||||
}
|
||||
|
||||
public SetPassword(Context ctx, Database db, String password, Uri keyfile, OnFinish finish, boolean dontSave) {
|
||||
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
@@ -55,16 +53,6 @@ public class SetPassword extends RunnableOnFinish {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public boolean validatePassword(Context ctx, DialogInterface.OnClickListener onclick) {
|
||||
if (!mDb.getPwDatabase().validatePasswordEncoding(mPassword)) {
|
||||
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
|
||||
dialog.show(ctx, onclick, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.getPwDatabase();
|
||||
@@ -88,14 +76,14 @@ public class SetPassword extends RunnableOnFinish {
|
||||
|
||||
// Save Database
|
||||
mFinish = new AfterSave(backupKey, mFinish);
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private class AfterSave extends OnFinishRunnable {
|
||||
private byte[] mBackup;
|
||||
|
||||
public AfterSave(byte[] backup, OnFinish finish) {
|
||||
public AfterSave(byte[] backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
|
||||
mBackup = backup;
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -26,13 +26,13 @@ import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwDatabase;
|
||||
import com.kunzisoft.keepass.utils.UriUtil;
|
||||
|
||||
public class CreateDB extends RunnableOnFinish {
|
||||
public class CreateDBRunnable extends RunnableOnFinish {
|
||||
|
||||
private String mFilename;
|
||||
private boolean mDontSave;
|
||||
private Context ctx;
|
||||
|
||||
public CreateDB(Context ctx, String filename, OnFinish finish, boolean dontSave) {
|
||||
public CreateDBRunnable(Context ctx, String filename, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
mFilename = filename;
|
||||
@@ -56,7 +56,7 @@ public class CreateDB extends RunnableOnFinish {
|
||||
App.clearShutdown();
|
||||
|
||||
// Commit changes
|
||||
SaveDB save = new SaveDB(ctx, db, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, db, mFinish, mDontSave);
|
||||
mFinish = null;
|
||||
save.run();
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -29,18 +29,18 @@ import com.kunzisoft.keepass.database.PwGroup;
|
||||
* @author bpellin
|
||||
*
|
||||
*/
|
||||
public class DeleteEntry extends RunnableOnFinish {
|
||||
public class DeleteEntryRunnable extends RunnableOnFinish {
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mEntry;
|
||||
private boolean mDontSave;
|
||||
private Context ctx;
|
||||
|
||||
public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish) {
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
|
||||
this(ctx, db, entry, finish, false);
|
||||
}
|
||||
|
||||
public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish, boolean dontSave) {
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -67,17 +67,17 @@ public class DeleteEntry extends RunnableOnFinish {
|
||||
mFinish = new AfterDelete(mFinish, parent, mEntry, recycle);
|
||||
|
||||
// Commit database
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterDelete extends OnFinish {
|
||||
private class AfterDelete extends OnFinishRunnable {
|
||||
|
||||
private PwGroup mParent;
|
||||
private PwEntry mEntry;
|
||||
private boolean recycled;
|
||||
|
||||
AfterDelete(OnFinish finish, PwGroup parent, PwEntry entry, boolean r) {
|
||||
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwEntry entry, boolean r) {
|
||||
super(finish);
|
||||
|
||||
mParent = parent;
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -29,19 +29,19 @@ import com.kunzisoft.keepass.database.PwGroup;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeleteGroup extends RunnableOnFinish {
|
||||
public class DeleteGroupRunnable extends RunnableOnFinish {
|
||||
|
||||
private Context mContext;
|
||||
private Database mDb;
|
||||
private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
|
||||
private boolean mDontSave;
|
||||
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinish finish) {
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, false);
|
||||
}
|
||||
|
||||
public DeleteGroup(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinish finish, boolean dontSave) {
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, dontSave);
|
||||
}
|
||||
@@ -67,14 +67,14 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
// Remove child entries
|
||||
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods
|
||||
for ( int i = 0; i < childEnt.size(); i++ ) {
|
||||
DeleteEntry task = new DeleteEntry(mContext, mDb, childEnt.get(i), null, true);
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(mContext, mDb, childEnt.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
|
||||
// Remove child groups
|
||||
List<PwGroup> childGrp = new ArrayList<>(mGroup.getChildGroups());
|
||||
for ( int i = 0; i < childGrp.size(); i++ ) {
|
||||
DeleteGroup task = new DeleteGroup(mContext, mDb, childGrp.get(i), null, true);
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(mContext, mDb, childGrp.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
mDb.deleteGroup(mGroup);
|
||||
@@ -88,17 +88,17 @@ public class DeleteGroup extends RunnableOnFinish {
|
||||
mFinish = new AfterDelete(mFinish, parent, mGroup, recycle);
|
||||
|
||||
// Commit Database
|
||||
SaveDB save = new SaveDB(mContext, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterDelete extends OnFinish {
|
||||
private class AfterDelete extends OnFinishRunnable {
|
||||
|
||||
private PwGroup mParent;
|
||||
private PwGroup mGroup;
|
||||
private boolean recycled;
|
||||
|
||||
AfterDelete(OnFinish finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
|
||||
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
|
||||
super(finish);
|
||||
|
||||
this.mParent = parent;
|
||||
@@ -17,17 +17,17 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class FileOnFinish extends OnFinish implements Serializable {
|
||||
public class FileOnFinishRunnable extends OnFinishRunnable implements Serializable {
|
||||
private Uri mFilename = null;
|
||||
protected FileOnFinish mOnFinish;
|
||||
protected FileOnFinishRunnable mOnFinish;
|
||||
|
||||
public FileOnFinish(FileOnFinish finish) {
|
||||
public FileOnFinishRunnable(FileOnFinishRunnable finish) {
|
||||
super(finish);
|
||||
|
||||
mOnFinish = finish;
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
@@ -40,7 +40,7 @@ import com.kunzisoft.keepass.database.exception.KeyFileEmptyException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LoadDB extends RunnableOnFinish {
|
||||
public class LoadDBRunnable extends RunnableOnFinish {
|
||||
private Uri mUri;
|
||||
private String mPass;
|
||||
private Uri mKey;
|
||||
@@ -48,7 +48,7 @@ public class LoadDB extends RunnableOnFinish {
|
||||
private Context mCtx;
|
||||
private boolean mRememberKeyfile;
|
||||
|
||||
public LoadDB(Database db, Context ctx, Uri uri, String pass, Uri key, OnFinish finish) {
|
||||
public LoadDBRunnable(Database db, Context ctx, Uri uri, String pass, Uri key, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
@@ -29,27 +29,27 @@ import android.widget.Toast;
|
||||
* @author bpellin
|
||||
*
|
||||
*/
|
||||
public class OnFinish implements Runnable {
|
||||
public class OnFinishRunnable implements Runnable {
|
||||
protected boolean mSuccess;
|
||||
protected String mMessage;
|
||||
|
||||
protected OnFinish mOnFinish;
|
||||
protected OnFinishRunnable mOnFinish;
|
||||
protected Handler mHandler;
|
||||
|
||||
public OnFinish() {
|
||||
public OnFinishRunnable() {
|
||||
}
|
||||
|
||||
public OnFinish(Handler handler) {
|
||||
public OnFinishRunnable(Handler handler) {
|
||||
mOnFinish = null;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public OnFinish(OnFinish finish, Handler handler) {
|
||||
public OnFinishRunnable(OnFinishRunnable finish, Handler handler) {
|
||||
mOnFinish = finish;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public OnFinish(OnFinish finish) {
|
||||
public OnFinishRunnable(OnFinishRunnable finish) {
|
||||
mOnFinish = finish;
|
||||
mHandler = null;
|
||||
}
|
||||
@@ -75,7 +75,8 @@ public class OnFinish implements Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO Move
|
||||
protected void displayMessage(Context ctx) {
|
||||
if ( mMessage != null && mMessage.length() > 0 ) {
|
||||
Toast.makeText(ctx, mMessage, Toast.LENGTH_LONG).show();
|
||||
@@ -17,17 +17,17 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
|
||||
|
||||
public abstract class RunnableOnFinish implements Runnable {
|
||||
|
||||
public OnFinish mFinish;
|
||||
public UpdateStatus mStatus;
|
||||
public OnFinishRunnable mFinish;
|
||||
public ProgressTaskUpdater mStatus;
|
||||
|
||||
public RunnableOnFinish(OnFinish finish) {
|
||||
public RunnableOnFinish(OnFinishRunnable finish) {
|
||||
mFinish = finish;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public abstract class RunnableOnFinish implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatus(UpdateStatus status) {
|
||||
public void setUpdateProgressTaskStatus(ProgressTaskUpdater status) {
|
||||
mStatus = status;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -26,12 +26,12 @@ import com.kunzisoft.keepass.database.exception.PwDbOutputException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SaveDB extends RunnableOnFinish {
|
||||
public class SaveDBRunnable extends RunnableOnFinish {
|
||||
private Database mDb;
|
||||
private boolean mDontSave;
|
||||
private Context mCtx;
|
||||
|
||||
public SaveDB(Context ctx, Database db, OnFinish finish, boolean dontSave) {
|
||||
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
@@ -39,7 +39,7 @@ public class SaveDB extends RunnableOnFinish {
|
||||
mCtx = ctx;
|
||||
}
|
||||
|
||||
public SaveDB(Context ctx, Database db, OnFinish finish) {
|
||||
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
|
||||
mDb = db;
|
||||
@@ -17,14 +17,14 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
|
||||
public class UpdateEntry extends RunnableOnFinish {
|
||||
public class UpdateEntryRunnable extends RunnableOnFinish {
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mOldE;
|
||||
@@ -32,11 +32,11 @@ public class UpdateEntry extends RunnableOnFinish {
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
|
||||
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish) {
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish) {
|
||||
this(ctx, db, oldE, newE, finish, false);
|
||||
}
|
||||
|
||||
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish, boolean dontSave) {
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -59,14 +59,14 @@ public class UpdateEntry extends RunnableOnFinish {
|
||||
mOldE.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterUpdate extends OnFinish {
|
||||
private class AfterUpdate extends OnFinishRunnable {
|
||||
private PwEntry mBackup;
|
||||
|
||||
AfterUpdate(PwEntry backup, OnFinish finish) {
|
||||
AfterUpdate(PwEntry backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
mBackup = backup;
|
||||
}
|
||||
@@ -17,14 +17,14 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.edit;
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class UpdateGroup extends RunnableOnFinish {
|
||||
public class UpdateGroupRunnable extends RunnableOnFinish {
|
||||
|
||||
private Database mDb;
|
||||
private PwGroup mOldGroup;
|
||||
@@ -32,11 +32,11 @@ public class UpdateGroup extends RunnableOnFinish {
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
|
||||
public UpdateGroup(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish) {
|
||||
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, oldGroup, newGroup, finish, false);
|
||||
}
|
||||
|
||||
public UpdateGroup(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -59,13 +59,13 @@ public class UpdateGroup extends RunnableOnFinish {
|
||||
mOldGroup.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
new SaveDB(ctx, mDb, mFinish, mDontSave).run();
|
||||
new SaveDBRunnable(ctx, mDb, mFinish, mDontSave).run();
|
||||
}
|
||||
|
||||
private class AfterUpdate extends OnFinish {
|
||||
private class AfterUpdate extends OnFinishRunnable {
|
||||
private PwGroup mBackup;
|
||||
|
||||
AfterUpdate(PwGroup backup, OnFinish finish) {
|
||||
AfterUpdate(PwGroup backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
mBackup = backup;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ package com.kunzisoft.keepass.database.load;
|
||||
|
||||
import com.kunzisoft.keepass.database.PwDatabase;
|
||||
import com.kunzisoft.keepass.database.exception.InvalidDBException;
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -33,8 +33,7 @@ public abstract class Importer {
|
||||
public abstract PwDatabase openDatabase(InputStream inStream, String password, InputStream keyInputStream)
|
||||
throws IOException, InvalidDBException;
|
||||
|
||||
public abstract PwDatabase openDatabase(InputStream inStream, String password, InputStream keyInputStream, UpdateStatus status, long roundsFix)
|
||||
public abstract PwDatabase openDatabase(InputStream inStream, String password, InputStream keyInputStream, ProgressTaskUpdater updater, long roundsFix)
|
||||
throws IOException, InvalidDBException;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ import com.kunzisoft.keepass.database.exception.InvalidPasswordException;
|
||||
import com.kunzisoft.keepass.stream.LEDataInputStream;
|
||||
import com.kunzisoft.keepass.stream.LEDataOutputStream;
|
||||
import com.kunzisoft.keepass.stream.NullOutputStream;
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
import com.kunzisoft.keepass.utils.Types;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -124,15 +124,15 @@ public class ImporterV3 extends Importer {
|
||||
* @throws InvalidAlgorithmParameterException if error decrypting main file body.
|
||||
* @throws ShortBufferException if error decrypting main file body.
|
||||
*/
|
||||
@Override
|
||||
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs)
|
||||
throws IOException, InvalidDBException
|
||||
{
|
||||
return openDatabase(inStream, password, kfIs, new UpdateStatus(), 0);
|
||||
throws IOException, InvalidDBException {
|
||||
return openDatabase(inStream, password, kfIs, null, 0);
|
||||
}
|
||||
|
||||
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs, UpdateStatus status, long roundsFix)
|
||||
throws IOException, InvalidDBException
|
||||
{
|
||||
@Override
|
||||
public PwDatabaseV3 openDatabase(InputStream inStream, String password, InputStream kfIs, ProgressTaskUpdater progressTaskUpdater, long roundsFix)
|
||||
throws IOException, InvalidDBException {
|
||||
PwDatabaseV3 newManager;
|
||||
|
||||
|
||||
@@ -156,7 +156,8 @@ public class ImporterV3 extends Importer {
|
||||
throw new InvalidDBVersionException();
|
||||
}
|
||||
|
||||
status.updateMessage(R.string.creating_db_key);
|
||||
if (progressTaskUpdater != null)
|
||||
progressTaskUpdater.updateMessage(R.string.creating_db_key);
|
||||
newManager = createDB();
|
||||
newManager.setMasterKey(password, kfIs);
|
||||
|
||||
@@ -177,7 +178,8 @@ public class ImporterV3 extends Importer {
|
||||
// Generate transformedMasterKey from masterKey
|
||||
newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.getNumberKeyEncryptionRounds());
|
||||
|
||||
status.updateMessage(R.string.decrypting_db);
|
||||
if (progressTaskUpdater != null)
|
||||
progressTaskUpdater.updateMessage(R.string.decrypting_db);
|
||||
// Initialize Rijndael algorithm
|
||||
Cipher cipher;
|
||||
try {
|
||||
|
||||
@@ -21,7 +21,7 @@ package com.kunzisoft.keepass.database.load;
|
||||
|
||||
import com.kunzisoft.keepass.database.PwDatabaseV3Debug;
|
||||
import com.kunzisoft.keepass.database.exception.InvalidDBException;
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -35,7 +35,7 @@ public class ImporterV3Debug extends ImporterV3 {
|
||||
|
||||
@Override
|
||||
public PwDatabaseV3Debug openDatabase(InputStream inStream, String password,
|
||||
InputStream keyInputStream, UpdateStatus status, long roundsFix) throws IOException,
|
||||
InputStream keyInputStream, ProgressTaskUpdater status, long roundsFix) throws IOException,
|
||||
InvalidDBException {
|
||||
return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyInputStream, status,
|
||||
roundsFix);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.load;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.crypto.CipherFactory;
|
||||
import com.kunzisoft.keepass.crypto.PwStreamCipherFactory;
|
||||
import com.kunzisoft.keepass.crypto.engine.CipherEngine;
|
||||
@@ -42,7 +43,7 @@ import com.kunzisoft.keepass.stream.BetterCipherInputStream;
|
||||
import com.kunzisoft.keepass.stream.HashedBlockInputStream;
|
||||
import com.kunzisoft.keepass.stream.HmacBlockInputStream;
|
||||
import com.kunzisoft.keepass.stream.LEDataInputStream;
|
||||
import com.kunzisoft.keepass.tasks.UpdateStatus;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater;
|
||||
import com.kunzisoft.keepass.utils.DateUtil;
|
||||
import com.kunzisoft.keepass.utils.EmptyUtils;
|
||||
import com.kunzisoft.keepass.utils.MemUtil;
|
||||
@@ -97,13 +98,16 @@ public class ImporterV4 extends Importer {
|
||||
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
||||
InputStream keyInputStream) throws IOException, InvalidDBException {
|
||||
|
||||
return openDatabase(inStream, password, keyInputStream, new UpdateStatus(), 0);
|
||||
return openDatabase(inStream, password, keyInputStream, null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PwDatabaseV4 openDatabase(InputStream inStream, String password,
|
||||
InputStream keyInputStream, UpdateStatus status, long roundsFix) throws IOException,
|
||||
InputStream keyInputStream, ProgressTaskUpdater progressTaskUpdater, long roundsFix) throws IOException,
|
||||
InvalidDBException {
|
||||
|
||||
if (progressTaskUpdater != null)
|
||||
progressTaskUpdater.updateMessage(R.string.creating_db_key);
|
||||
db = createDB();
|
||||
|
||||
PwDbHeaderV4 header = new PwDbHeaderV4(db);
|
||||
@@ -118,6 +122,8 @@ public class ImporterV4 extends Importer {
|
||||
db.setMasterKey(password, keyInputStream);
|
||||
db.makeFinalKey(header.masterSeed, db.getKdfParameters(), roundsFix);
|
||||
|
||||
if (progressTaskUpdater != null)
|
||||
progressTaskUpdater.updateMessage(R.string.decrypting_db);
|
||||
CipherEngine engine;
|
||||
Cipher cipher;
|
||||
try {
|
||||
|
||||
@@ -51,8 +51,8 @@ import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.activities.GroupActivity;
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.autofill.AutofillHelper;
|
||||
import com.kunzisoft.keepass.database.edit.CreateDB;
|
||||
import com.kunzisoft.keepass.database.edit.FileOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.CreateDBRunnable;
|
||||
import com.kunzisoft.keepass.database.action.FileOnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.exception.ContentFileNotFoundException;
|
||||
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.CreateFileDialogFragment;
|
||||
@@ -60,7 +60,8 @@ import com.kunzisoft.keepass.password.AssignPasswordHelper;
|
||||
import com.kunzisoft.keepass.password.PasswordActivity;
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil;
|
||||
import com.kunzisoft.keepass.stylish.StylishActivity;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
import com.kunzisoft.keepass.utils.EmptyUtils;
|
||||
import com.kunzisoft.keepass.utils.MenuUtil;
|
||||
import com.kunzisoft.keepass.utils.UriUtil;
|
||||
@@ -515,22 +516,26 @@ public class FileSelectActivity extends StylishActivity implements
|
||||
|
||||
// Prep an object to collect a password once the database has
|
||||
// been created
|
||||
FileOnFinish launchActivityOnFinish = new FileOnFinish(
|
||||
FileOnFinishRunnable launchActivityOnFinish = new FileOnFinishRunnable(
|
||||
new LaunchGroupActivity(databaseFilename));
|
||||
AssignPasswordOnFinish assignPasswordOnFinish =
|
||||
new AssignPasswordOnFinish(launchActivityOnFinish);
|
||||
|
||||
// Create the new database
|
||||
CreateDB create = new CreateDB(FileSelectActivity.this,
|
||||
databaseFilename, assignPasswordOnFinish, true);
|
||||
|
||||
ProgressTask createTask = new ProgressTask(
|
||||
FileSelectActivity.this, create,
|
||||
R.string.progress_create);
|
||||
createTask.run();
|
||||
|
||||
// Initialize the password helper assigner to set the password after the database creation
|
||||
assignPasswordHelper = new AssignPasswordHelper(this,
|
||||
masterPasswordChecked, masterPassword, keyFileChecked, keyFile);
|
||||
assignPasswordHelper.setCreateProgressDialog(false);
|
||||
|
||||
// Create the new database
|
||||
CreateDBRunnable createDBTask = new CreateDBRunnable(FileSelectActivity.this,
|
||||
databaseFilename, assignPasswordOnFinish, true);
|
||||
createDBTask.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
ProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager(),
|
||||
R.string.progress_create)
|
||||
));
|
||||
new Thread(createDBTask).start();
|
||||
|
||||
} catch (Exception e) {
|
||||
String error = "Unable to create database with this password and key file";
|
||||
@@ -546,21 +551,23 @@ public class FileSelectActivity extends StylishActivity implements
|
||||
|
||||
}
|
||||
|
||||
private class AssignPasswordOnFinish extends FileOnFinish {
|
||||
private class AssignPasswordOnFinish extends FileOnFinishRunnable {
|
||||
|
||||
AssignPasswordOnFinish(FileOnFinish fileOnFinish) {
|
||||
AssignPasswordOnFinish(FileOnFinishRunnable fileOnFinish) {
|
||||
super(fileOnFinish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mSuccess) {
|
||||
assignPasswordHelper.assignPasswordInDatabase(mOnFinish);
|
||||
// Dont use ProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
// assignPasswordHelper do it
|
||||
runOnUiThread(() -> assignPasswordHelper.assignPasswordInDatabase(mOnFinish));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LaunchGroupActivity extends FileOnFinish {
|
||||
private class LaunchGroupActivity extends FileOnFinishRunnable {
|
||||
private Uri mUri;
|
||||
|
||||
LaunchGroupActivity(String filename) {
|
||||
|
||||
@@ -19,25 +19,30 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.password;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.edit.FileOnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.SetPassword;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.database.action.AssignPasswordInDBRunnable;
|
||||
import com.kunzisoft.keepass.database.action.FileOnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
|
||||
public class AssignPasswordHelper {
|
||||
|
||||
private Context context;
|
||||
private AppCompatActivity context;
|
||||
|
||||
private String masterPassword = null;
|
||||
private Uri keyfile = null;
|
||||
|
||||
public AssignPasswordHelper(Context context,
|
||||
private boolean createProgressDialog;
|
||||
|
||||
public AssignPasswordHelper(AppCompatActivity context,
|
||||
boolean withMasterPassword,
|
||||
String masterPassword,
|
||||
boolean withKeyFile,
|
||||
@@ -47,36 +52,66 @@ public class AssignPasswordHelper {
|
||||
this.masterPassword = masterPassword;
|
||||
if (withKeyFile)
|
||||
this.keyfile = keyfile;
|
||||
|
||||
createProgressDialog = true;
|
||||
}
|
||||
|
||||
public void assignPasswordInDatabase(FileOnFinish fileOnFinish) {
|
||||
SetPassword sp = new SetPassword(context, App.getDB(), masterPassword, keyfile, new AfterSave(fileOnFinish, new Handler()));
|
||||
final ProgressTask pt = new ProgressTask(context, sp, R.string.saving_database);
|
||||
boolean valid = sp.validatePassword(context, (dialog, which) -> pt.run());
|
||||
public void setCreateProgressDialog(boolean createProgressDialog) {
|
||||
this.createProgressDialog = createProgressDialog;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
pt.run();
|
||||
public void assignPasswordInDatabase(FileOnFinishRunnable fileOnFinish) {
|
||||
AssignPasswordInDBRunnable assignPasswordInDBRunnable = new AssignPasswordInDBRunnable(
|
||||
context,
|
||||
App.getDB(),
|
||||
masterPassword,
|
||||
keyfile,
|
||||
new AfterSave(fileOnFinish, new Handler())
|
||||
);
|
||||
if (createProgressDialog) {
|
||||
assignPasswordInDBRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(context,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
context.getSupportFragmentManager())
|
||||
));
|
||||
}
|
||||
Thread taskThread = new Thread(assignPasswordInDBRunnable);
|
||||
|
||||
// Show the progress dialog now or after dialog confirmation
|
||||
if (App.getDB().getPwDatabase().validatePasswordEncoding(masterPassword)) {
|
||||
taskThread.start();
|
||||
} else {
|
||||
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
|
||||
dialog.show(context, (newDialog, which) -> taskThread.start(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private FileOnFinish mFinish;
|
||||
private class AfterSave extends OnFinishRunnable {
|
||||
private FileOnFinishRunnable mFinish;
|
||||
|
||||
public AfterSave(FileOnFinish finish, Handler handler) {
|
||||
AfterSave(FileOnFinishRunnable finish, Handler handler) {
|
||||
super(finish, handler);
|
||||
mFinish = finish;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
if ( mFinish != null ) {
|
||||
mFinish.setFilename(keyfile);
|
||||
}
|
||||
} else {
|
||||
displayMessage(context);
|
||||
}
|
||||
super.run();
|
||||
|
||||
context.runOnUiThread(() -> {
|
||||
if ( mSuccess ) {
|
||||
if ( mFinish != null ) {
|
||||
mFinish.setFilename(keyfile);
|
||||
}
|
||||
} else {
|
||||
if ( mMessage != null && mMessage.length() > 0 ) {
|
||||
Toast.makeText(context, mMessage, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
// To remove progress task
|
||||
ProgressTaskDialogFragment.stop(context.getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ import com.kunzisoft.keepass.compat.BackupManagerCompat;
|
||||
import com.kunzisoft.keepass.compat.ClipDataCompat;
|
||||
import com.kunzisoft.keepass.compat.EditorCompat;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.edit.LoadDB;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.action.LoadDBRunnable;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper;
|
||||
import com.kunzisoft.keepass.fileselect.KeyFileHelper;
|
||||
import com.kunzisoft.keepass.fingerprint.FingerPrintAnimatedVector;
|
||||
@@ -71,7 +71,8 @@ import com.kunzisoft.keepass.fingerprint.FingerPrintDialog;
|
||||
import com.kunzisoft.keepass.fingerprint.FingerPrintHelper;
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil;
|
||||
import com.kunzisoft.keepass.stylish.StylishActivity;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
import com.kunzisoft.keepass.utils.EmptyUtils;
|
||||
import com.kunzisoft.keepass.utils.MenuUtil;
|
||||
import com.kunzisoft.keepass.utils.UriUtil;
|
||||
@@ -122,6 +123,8 @@ public class PasswordActivity extends StylishActivity
|
||||
private CompoundButton checkboxKeyfileView;
|
||||
private CompoundButton checkboxDefaultDatabaseView;
|
||||
|
||||
private ProgressTaskDialogFragment loadingDatabaseDialog;
|
||||
|
||||
private DefaultCheckChange defaultCheckChange;
|
||||
private ValidateButtonViewClickListener validateButtonViewClickListener;
|
||||
|
||||
@@ -808,20 +811,86 @@ public class PasswordActivity extends StylishActivity
|
||||
loadDatabase(password, keyUri);
|
||||
}
|
||||
|
||||
private void loadDatabase(String pass, Uri keyfile) {
|
||||
private void loadDatabase(String password, Uri keyfile) {
|
||||
// Clear before we load
|
||||
Database db = App.getDB();
|
||||
db.clear();
|
||||
|
||||
Database database = App.getDB();
|
||||
database.clear();
|
||||
// Clear the shutdown flag
|
||||
App.clearShutdown();
|
||||
|
||||
// Show the progress dialog
|
||||
Handler handler = new Handler();
|
||||
AfterLoad afterLoad = new AfterLoad(handler, db);
|
||||
AfterLoadingDatabase afterLoad = new AfterLoadingDatabase(handler, database);
|
||||
LoadDBRunnable databaseLoadingTask = new LoadDBRunnable(
|
||||
database,
|
||||
PasswordActivity.this,
|
||||
mDbUri,
|
||||
password,
|
||||
keyfile,
|
||||
afterLoad);
|
||||
databaseLoadingTask.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
handler,
|
||||
ProgressTaskDialogFragment.start(
|
||||
getSupportFragmentManager(),
|
||||
R.string.loading_database)
|
||||
));
|
||||
Thread t = new Thread(databaseLoadingTask);
|
||||
t.start();
|
||||
}
|
||||
|
||||
LoadDB task = new LoadDB(db, PasswordActivity.this, mDbUri, pass, keyfile, afterLoad);
|
||||
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
|
||||
pt.run();
|
||||
/**
|
||||
* Called after verify and try to opening the database
|
||||
*/
|
||||
private final class AfterLoadingDatabase extends OnFinishRunnable {
|
||||
|
||||
protected Database db;
|
||||
|
||||
AfterLoadingDatabase(
|
||||
Handler handler,
|
||||
Database db) {
|
||||
super(handler);
|
||||
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
runOnUiThread(() -> {
|
||||
// Recheck fingerprint if error
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Stay with the same mode
|
||||
reInitWithFingerprintMode();
|
||||
}
|
||||
|
||||
if (db.isPasswordEncodingError()) {
|
||||
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
|
||||
dialog.show(PasswordActivity.this, (dialog1, which) -> launchGroupActivity());
|
||||
} else if (mSuccess) {
|
||||
launchGroupActivity();
|
||||
} else {
|
||||
if ( mMessage != null && mMessage.length() > 0 ) {
|
||||
Toast.makeText(PasswordActivity.this, mMessage, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
// To remove progress task
|
||||
ProgressTaskDialogFragment.stop(getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void launchGroupActivity() {
|
||||
AssistStructure assistStructure = null;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
assistStructure = autofillHelper.getAssistStructure();
|
||||
if (assistStructure != null) {
|
||||
GroupActivity.launch(PasswordActivity.this, assistStructure);
|
||||
}
|
||||
}
|
||||
if (assistStructure == null) {
|
||||
GroupActivity.launch(PasswordActivity.this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -863,54 +932,6 @@ public class PasswordActivity extends StylishActivity
|
||||
PasswordActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after verify and try to opening the database
|
||||
*/
|
||||
private final class AfterLoad extends OnFinish {
|
||||
|
||||
protected Database db;
|
||||
|
||||
AfterLoad(
|
||||
Handler handler,
|
||||
Database db) {
|
||||
super(handler);
|
||||
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
// Recheck fingerprint if error
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Stay with the same mode
|
||||
reInitWithFingerprintMode();
|
||||
}
|
||||
|
||||
if (db.isPasswordEncodingError()) {
|
||||
PasswordEncodingDialogHelper dialog = new PasswordEncodingDialogHelper();
|
||||
dialog.show(PasswordActivity.this, (dialog1, which) -> launchGroupActivity());
|
||||
} else if (mSuccess) {
|
||||
launchGroupActivity();
|
||||
} else {
|
||||
displayMessage(PasswordActivity.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void launchGroupActivity() {
|
||||
AssistStructure assistStructure = null;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
assistStructure = autofillHelper.getAssistStructure();
|
||||
if (assistStructure != null) {
|
||||
GroupActivity.launch(PasswordActivity.this, assistStructure);
|
||||
}
|
||||
}
|
||||
if (assistStructure == null) {
|
||||
GroupActivity.launch(PasswordActivity.this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class UriIntentInitTask extends AsyncTask<Intent, Void, Integer> {
|
||||
|
||||
static final String KEY_FILENAME = "fileName";
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.kunzisoft.keepass.settings.preferenceDialogFragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
|
||||
public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
|
||||
|
||||
@@ -37,22 +38,22 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
|
||||
database.assignDescription(dbDescription);
|
||||
|
||||
Handler handler = new Handler();
|
||||
setAfterSaveDatabase(new AfterDescriptionSave(getContext(), handler, dbDescription, oldDescription));
|
||||
setAfterSaveDatabase(new AfterDescriptionSave((AppCompatActivity) getActivity(), handler, dbDescription, oldDescription));
|
||||
}
|
||||
|
||||
super.onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
private class AfterDescriptionSave extends OnFinish {
|
||||
private class AfterDescriptionSave extends OnFinishRunnable {
|
||||
|
||||
private AppCompatActivity mActivity;
|
||||
private String mNewDescription;
|
||||
private String mOldDescription;
|
||||
private Context mCtx;
|
||||
|
||||
AfterDescriptionSave(Context ctx, Handler handler, String newDescription, String oldDescription) {
|
||||
AfterDescriptionSave(AppCompatActivity ctx, Handler handler, String newDescription, String oldDescription) {
|
||||
super(handler);
|
||||
|
||||
mCtx = ctx;
|
||||
mActivity = ctx;
|
||||
mNewDescription = newDescription;
|
||||
mOldDescription = oldDescription;
|
||||
}
|
||||
@@ -62,12 +63,18 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
|
||||
String descriptionToShow = mNewDescription;
|
||||
|
||||
if (!mSuccess) {
|
||||
displayMessage(mCtx);
|
||||
displayMessage(mActivity);
|
||||
database.assignDescription(mOldDescription);
|
||||
database.assignDescription(mOldDescription);
|
||||
}
|
||||
|
||||
getPreference().setSummary(descriptionToShow);
|
||||
if (mActivity != null) {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
getPreference().setSummary(descriptionToShow);
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(
|
||||
mActivity.getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.kunzisoft.keepass.settings.preferenceDialogFragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
|
||||
public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
|
||||
|
||||
@@ -37,22 +38,22 @@ public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePref
|
||||
database.assignName(dbName);
|
||||
|
||||
Handler handler = new Handler();
|
||||
setAfterSaveDatabase(new AfterNameSave(getContext(), handler, dbName, oldName));
|
||||
setAfterSaveDatabase(new AfterNameSave((AppCompatActivity) getActivity(), handler, dbName, oldName));
|
||||
}
|
||||
|
||||
super.onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
private class AfterNameSave extends OnFinish {
|
||||
private class AfterNameSave extends OnFinishRunnable {
|
||||
|
||||
private String mNewName;
|
||||
private String mOldName;
|
||||
private Context mCtx;
|
||||
private AppCompatActivity mActivity;
|
||||
|
||||
AfterNameSave(Context ctx, Handler handler, String newName, String oldName) {
|
||||
AfterNameSave(AppCompatActivity ctx, Handler handler, String newName, String oldName) {
|
||||
super(handler);
|
||||
|
||||
mCtx = ctx;
|
||||
mActivity = ctx;
|
||||
mNewName = newName;
|
||||
mOldName = oldName;
|
||||
}
|
||||
@@ -62,11 +63,18 @@ public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePref
|
||||
String nameToShow = mNewName;
|
||||
|
||||
if (!mSuccess) {
|
||||
displayMessage(mCtx);
|
||||
displayMessage(mActivity);
|
||||
database.assignName(mOldName);
|
||||
}
|
||||
|
||||
getPreference().setSummary(nameToShow);
|
||||
|
||||
if (mActivity != null) {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
getPreference().setSummary(nameToShow);
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(
|
||||
mActivity.getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@ package com.kunzisoft.keepass.settings.preferenceDialogFragment;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.SaveDB;
|
||||
import com.kunzisoft.keepass.tasks.ProgressTask;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.action.SaveDBRunnable;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
|
||||
public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputPreferenceDialogFragmentCompat {
|
||||
|
||||
protected Database database;
|
||||
|
||||
private OnFinish afterSaveDatabase;
|
||||
private OnFinishRunnable afterSaveDatabase;
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
@@ -25,17 +25,21 @@ public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputP
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
if ( positiveResult ) {
|
||||
assert getContext() != null;
|
||||
assert getActivity() != null;
|
||||
|
||||
if (database != null && afterSaveDatabase != null) {
|
||||
SaveDB save = new SaveDB(getContext(), database, afterSaveDatabase);
|
||||
ProgressTask pt = new ProgressTask(getContext(), save, R.string.saving_database);
|
||||
pt.run();
|
||||
SaveDBRunnable saveDBRunnable = new SaveDBRunnable(getContext(), database, afterSaveDatabase);
|
||||
saveDBRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(getContext(),
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getActivity().getSupportFragmentManager())
|
||||
));
|
||||
new Thread(saveDBRunnable).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setAfterSaveDatabase(OnFinish afterSaveDatabase) {
|
||||
public void setAfterSaveDatabase(OnFinishRunnable afterSaveDatabase) {
|
||||
this.afterSaveDatabase = afterSaveDatabase;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,15 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.settings.preferenceDialogFragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
|
||||
public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
|
||||
|
||||
@@ -76,22 +77,22 @@ public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreference
|
||||
}
|
||||
|
||||
Handler handler = new Handler();
|
||||
setAfterSaveDatabase(new AfterRoundSave(getContext(), handler, rounds, oldRounds));
|
||||
setAfterSaveDatabase(new AfterRoundSave((AppCompatActivity) getActivity(), handler, rounds, oldRounds));
|
||||
}
|
||||
|
||||
super.onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
private class AfterRoundSave extends OnFinish {
|
||||
private class AfterRoundSave extends OnFinishRunnable {
|
||||
|
||||
private long mNewRounds;
|
||||
private long mOldRounds;
|
||||
private Context mCtx;
|
||||
private AppCompatActivity mActivity;
|
||||
|
||||
AfterRoundSave(Context ctx, Handler handler, long newRounds, long oldRounds) {
|
||||
AfterRoundSave(AppCompatActivity ctx, Handler handler, long newRounds, long oldRounds) {
|
||||
super(handler);
|
||||
|
||||
mCtx = ctx;
|
||||
mActivity = ctx;
|
||||
mNewRounds = newRounds;
|
||||
mOldRounds = oldRounds;
|
||||
}
|
||||
@@ -101,11 +102,17 @@ public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreference
|
||||
long roundsToShow = mNewRounds;
|
||||
|
||||
if (!mSuccess) {
|
||||
displayMessage(mCtx);
|
||||
displayMessage(mActivity);
|
||||
database.setNumberKeyEncryptionRounds(mOldRounds);
|
||||
}
|
||||
|
||||
getPreference().setSummary(String.valueOf(roundsToShow));
|
||||
if (mActivity != null) {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
getPreference().setSummary(String.valueOf(roundsToShow));
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(
|
||||
mActivity.getSupportFragmentManager());
|
||||
});
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.tasks;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.database.edit.OnFinish;
|
||||
import com.kunzisoft.keepass.database.edit.RunnableOnFinish;
|
||||
|
||||
/** Designed to Pop up a progress dialog, run a thread in the background,
|
||||
* run cleanup in the current thread, close the dialog. Without blocking
|
||||
* the current thread.
|
||||
*
|
||||
* @author bpellin
|
||||
*
|
||||
*/
|
||||
public class ProgressTask implements Runnable {
|
||||
private Context mCtx;
|
||||
private Handler mHandler;
|
||||
private RunnableOnFinish mTask;
|
||||
private ProgressDialog mPd;
|
||||
|
||||
public ProgressTask(Context ctx, RunnableOnFinish task, int messageId) {
|
||||
mCtx = ctx;
|
||||
mTask = task;
|
||||
mHandler = new Handler();
|
||||
|
||||
// Show process dialog
|
||||
mPd = new ProgressDialog(mCtx);
|
||||
mPd.setCanceledOnTouchOutside(false);
|
||||
mPd.setTitle(ctx.getText(R.string.progress_title));
|
||||
mPd.setMessage(ctx.getText(messageId));
|
||||
|
||||
// Set code to run when this is finished
|
||||
mTask.setStatus(new UpdateStatus(ctx, mHandler, mPd));
|
||||
mTask.mFinish = new AfterTask(task.mFinish, mHandler);
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Show process dialog
|
||||
mPd.show();
|
||||
|
||||
// Start Thread to Run task
|
||||
Thread t = new Thread(mTask);
|
||||
t.start();
|
||||
}
|
||||
|
||||
private class AfterTask extends OnFinish {
|
||||
|
||||
public AfterTask(OnFinish finish, Handler handler) {
|
||||
super(finish, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
// Remove the progress dialog
|
||||
mHandler.post(new CloseProcessDialog());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class CloseProcessDialog implements Runnable {
|
||||
public void run() {
|
||||
if (mPd != null && mPd.isShowing()) {
|
||||
mPd.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2018 Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.tasks;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class ProgressTaskDialogFragment extends DialogFragment implements ProgressTaskUpdater{
|
||||
|
||||
public static final String PROGRESS_TASK_DIALOG_TAG = "progressDialogFragment";
|
||||
|
||||
private static final int UNDEFINED = -1;
|
||||
|
||||
private @StringRes int title = UNDEFINED;
|
||||
private @StringRes int message = UNDEFINED;
|
||||
|
||||
private TextView titleView;
|
||||
private TextView messageView;
|
||||
private ProgressBar progressView;
|
||||
|
||||
public static ProgressTaskDialogFragment start(FragmentManager fragmentManager, @StringRes int titleId) {
|
||||
// Create an instance of the dialog fragment and show it
|
||||
ProgressTaskDialogFragment dialog = new ProgressTaskDialogFragment();
|
||||
dialog.updateTitle(titleId);
|
||||
dialog.show(fragmentManager, PROGRESS_TASK_DIALOG_TAG);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
assert getActivity() != null;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
// Get the layout inflater
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
|
||||
// Inflate and set the layout for the dialog
|
||||
// Pass null as the parent view because its going in the dialog layout
|
||||
@SuppressLint("InflateParams")
|
||||
View root = inflater.inflate(R.layout.progress_dialog, null);
|
||||
builder.setView(root);
|
||||
|
||||
titleView = root.findViewById(R.id.progress_dialog_title);
|
||||
messageView = root.findViewById(R.id.progress_dialog_message);
|
||||
progressView = root.findViewById(R.id.progress_dialog_bar);
|
||||
|
||||
updateTitle(title);
|
||||
updateMessage(message);
|
||||
|
||||
setCancelable(false);
|
||||
lockScreenOrientation();
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
unlockScreenOrientation();
|
||||
}
|
||||
|
||||
public static void stop(FragmentManager fragmentManager) {
|
||||
Fragment fragmentTask = fragmentManager.findFragmentByTag(PROGRESS_TASK_DIALOG_TAG);
|
||||
if (fragmentTask != null) {
|
||||
ProgressTaskDialogFragment loadingDatabaseDialog = (ProgressTaskDialogFragment) fragmentTask;
|
||||
loadingDatabaseDialog.dismissAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
|
||||
private void lockScreenOrientation() {
|
||||
if (getActivity() != null) {
|
||||
int currentOrientation = getResources().getConfiguration().orientation;
|
||||
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
} else {
|
||||
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unlockScreenOrientation() {
|
||||
if (getActivity() != null)
|
||||
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
||||
}
|
||||
|
||||
public void setTitle(@StringRes int titleId) {
|
||||
this.title = titleId;
|
||||
}
|
||||
|
||||
private void updateView(TextView textView, @StringRes int resId) {
|
||||
if (textView != null) {
|
||||
if (resId == UNDEFINED) {
|
||||
textView.setVisibility(View.GONE);
|
||||
} else {
|
||||
textView.setText(resId);
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTitle(int resId) {
|
||||
this.title = resId;
|
||||
updateView(titleView, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMessage(int resId) {
|
||||
this.message = resId;
|
||||
updateView(messageView, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2018 Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.tasks;
|
||||
|
||||
public interface ProgressTaskUpdater {
|
||||
void updateMessage(int resId);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.kunzisoft.keepass.tasks;
|
||||
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class SaveDatabaseProgressTaskDialogFragment extends ProgressTaskDialogFragment {
|
||||
|
||||
public static SaveDatabaseProgressTaskDialogFragment start(FragmentManager fragmentManager) {
|
||||
// Create an instance of the dialog fragment and show it
|
||||
SaveDatabaseProgressTaskDialogFragment dialog = new SaveDatabaseProgressTaskDialogFragment();
|
||||
dialog.updateTitle(R.string.saving_database);
|
||||
dialog.show(fragmentManager, PROGRESS_TASK_DIALOG_TAG);
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
@@ -19,27 +19,27 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.tasks;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
|
||||
public class UpdateStatus {
|
||||
private ProgressDialog mPD;
|
||||
private Context mCtx;
|
||||
public class UpdateProgressTaskStatus implements ProgressTaskUpdater {
|
||||
private Context mContext;
|
||||
private ProgressTaskUpdater mProgressTaskUpdater;
|
||||
private Handler mHandler;
|
||||
|
||||
public UpdateStatus() {
|
||||
|
||||
|
||||
public UpdateProgressTaskStatus(Context context, ProgressTaskUpdater progressTaskUpdater) {
|
||||
this(context, new Handler(), progressTaskUpdater);
|
||||
}
|
||||
|
||||
public UpdateStatus(Context ctx, Handler handler, ProgressDialog pd) {
|
||||
mCtx = ctx;
|
||||
mPD = pd;
|
||||
mHandler = handler;
|
||||
|
||||
public UpdateProgressTaskStatus(Context context, Handler handler, ProgressTaskUpdater progressTaskUpdater) {
|
||||
this.mContext = context;
|
||||
this.mProgressTaskUpdater = progressTaskUpdater;
|
||||
this.mHandler = handler;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateMessage(int resId) {
|
||||
if ( mCtx != null && mPD != null && mHandler != null ) {
|
||||
if ( mContext != null && mProgressTaskUpdater != null && mHandler != null ) {
|
||||
mHandler.post(new UpdateMessage(resId));
|
||||
}
|
||||
}
|
||||
@@ -47,13 +47,12 @@ public class UpdateStatus {
|
||||
private class UpdateMessage implements Runnable {
|
||||
private int mResId;
|
||||
|
||||
public UpdateMessage(int resId) {
|
||||
UpdateMessage(int resId) {
|
||||
mResId = resId;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mPD.setMessage(mCtx.getString(mResId));
|
||||
mProgressTaskUpdater.updateMessage(mResId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,17 @@
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_dialog_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:max="100"
|
||||
android:backgroundTint="@color/white"
|
||||
android:visibility="gone"
|
||||
android:layout_above="@+id/pass_ok"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatButton
|
||||
android:id="@+id/pass_ok"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
38
app/src/main/res/layout/progress_dialog.xml
Normal file
38
app/src/main/res/layout/progress_dialog.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progress_dialog_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:textColor="?android:attr/textColor"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progress_dialog_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_dialog_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:indeterminate="true"
|
||||
android:max="100"/>
|
||||
|
||||
</LinearLayout>
|
||||
4
fastlane/metadata/android/en-US/changelogs/10.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/10.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
* Upgrade translations
|
||||
* Fix classic dark theme
|
||||
* Add Material Icon Pack to the Free version
|
||||
* Fix bugs
|
||||
4
fastlane/metadata/android/fr-FR/changelogs/10.txt
Normal file
4
fastlane/metadata/android/fr-FR/changelogs/10.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
* Mise à jour des traductions
|
||||
* Correction du thème sombre classic
|
||||
* Ajout du Pack d'Icones Material à la version gratuite
|
||||
* Corrections de bugs
|
||||
Reference in New Issue
Block a user