Refactor runnable action

This commit is contained in:
J-Jamet
2018-05-29 19:58:27 +02:00
parent 3b24f9d821
commit d9490f9840
23 changed files with 442 additions and 591 deletions

View File

@@ -19,8 +19,6 @@
*/
package com.kunzisoft.keepass.tests.database;
import java.util.List;
import android.content.Context;
import android.test.AndroidTestCase;
@@ -30,9 +28,11 @@ 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.action.DeleteGroupRunnable;
import com.kunzisoft.keepass.database.action.node.DeleteGroupRunnable;
import com.kunzisoft.keepass.search.SearchDbHelper;
import java.util.List;
public class DeleteEntry extends AndroidTestCase {
private static final String GROUP1_NAME = "Group1";
private static final String ENTRY1_NAME = "Test1";

View File

@@ -24,7 +24,6 @@ import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
@@ -49,10 +48,11 @@ 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.action.AddEntryRunnable;
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.action.RunnableOnFinish;
import com.kunzisoft.keepass.database.action.UpdateEntryRunnable;
import com.kunzisoft.keepass.database.action.node.AddEntryRunnable;
import com.kunzisoft.keepass.database.action.node.AfterActionNodeOnFinish;
import com.kunzisoft.keepass.database.action.node.UpdateEntryRunnable;
import com.kunzisoft.keepass.database.security.ProtectedString;
import com.kunzisoft.keepass.dialogs.GeneratePasswordDialogFragment;
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
@@ -67,6 +67,8 @@ import com.kunzisoft.keepass.view.EntryEditCustomField;
import java.util.UUID;
import javax.annotation.Nullable;
import static com.kunzisoft.keepass.dialogs.IconPickerDialogFragment.UNDEFINED_ICON_ID;
public class EntryEditActivity extends LockingHideActivity
@@ -251,7 +253,7 @@ public class EntryEditActivity extends LockingHideActivity
mCallbackNewEntry = populateNewEntry();
// Open a progress dialog and save entry
OnFinishRunnable onFinish = new AfterSave();
AfterActionNodeOnFinish onFinish = new AfterSave();
EntryEditActivity act = EntryEditActivity.this;
RunnableOnFinish task;
if ( mIsNew ) {
@@ -560,14 +562,10 @@ public class EntryEditActivity extends LockingHideActivity
}
}
private final class AfterSave extends OnFinishRunnable {
AfterSave() {
super(new Handler());
}
private final class AfterSave extends AfterActionNodeOnFinish {
@Override
public void run() {
public void run(@Nullable PwNode oldNode, @Nullable PwNode newNode) {
runOnUiThread(() -> {
if ( mSuccess ) {
finish();
@@ -578,6 +576,6 @@ public class EntryEditActivity extends LockingHideActivity
SaveDatabaseProgressTaskDialogFragment.stop(EntryEditActivity.this);
});
}
}
}
}

View File

@@ -58,15 +58,14 @@ import com.kunzisoft.keepass.database.PwGroupId;
import com.kunzisoft.keepass.database.PwIcon;
import com.kunzisoft.keepass.database.PwIconStandard;
import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.action.AddGroupRunnable;
import com.kunzisoft.keepass.database.action.AfterActionNodeOnFinish;
import com.kunzisoft.keepass.database.action.CopyEntryRunnable;
import com.kunzisoft.keepass.database.action.DeleteEntryRunnable;
import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
import com.kunzisoft.keepass.database.action.MoveEntryRunnable;
import com.kunzisoft.keepass.database.action.MoveGroupRunnable;
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.database.action.UpdateGroupRunnable;
import com.kunzisoft.keepass.database.action.node.AddGroupRunnable;
import com.kunzisoft.keepass.database.action.node.AfterActionNodeOnFinish;
import com.kunzisoft.keepass.database.action.node.CopyEntryRunnable;
import com.kunzisoft.keepass.database.action.node.DeleteEntryRunnable;
import com.kunzisoft.keepass.database.action.node.DeleteGroupRunnable;
import com.kunzisoft.keepass.database.action.node.MoveEntryRunnable;
import com.kunzisoft.keepass.database.action.node.MoveGroupRunnable;
import com.kunzisoft.keepass.database.action.node.UpdateGroupRunnable;
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment;
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
@@ -329,7 +328,7 @@ public class GroupActivity extends ListNodesActivity
private void copyNode(PwEntry entryToCopy, PwGroup newParent) {
CopyEntryRunnable task = new CopyEntryRunnable(this, App.getDB(), entryToCopy, newParent,
new AfterAddNode(new Handler()));
new AfterAddNode());
task.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -365,7 +364,7 @@ public class GroupActivity extends ListNodesActivity
private void moveGroup(PwGroup groupToMove, PwGroup newParent) {
MoveGroupRunnable task = new MoveGroupRunnable(this, App.getDB(), groupToMove, newParent,
new AfterAddNode(new Handler()));
new AfterAddNode());
task.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -376,7 +375,7 @@ public class GroupActivity extends ListNodesActivity
private void moveEntry(PwEntry entryToMove, PwGroup newParent) {
MoveEntryRunnable task = new MoveEntryRunnable(this, App.getDB(), entryToMove, newParent,
new AfterAddNode(new Handler()));
new AfterAddNode());
task.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -400,8 +399,11 @@ public class GroupActivity extends ListNodesActivity
private void deleteGroup(PwGroup group) {
//TODO Verify trash recycle bin
DeleteGroupRunnable task = new DeleteGroupRunnable(this, App.getDB(), group,
new AfterDeleteNode(new Handler(), group));
DeleteGroupRunnable task = new DeleteGroupRunnable(
this,
App.getDB(),
group,
new AfterDeleteNode());
task.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -411,8 +413,11 @@ public class GroupActivity extends ListNodesActivity
}
private void deleteEntry(PwEntry entry) {
DeleteEntryRunnable task = new DeleteEntryRunnable(this, App.getDB(), entry,
new AfterDeleteNode(new Handler(), entry));
DeleteEntryRunnable task = new DeleteEntryRunnable(
this,
App.getDB(),
entry,
new AfterDeleteNode());
task.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -674,7 +679,7 @@ public class GroupActivity extends ListNodesActivity
AddGroupRunnable addGroupRunnable = new AddGroupRunnable(this,
App.getDB(),
newGroup,
new AfterAddNode(new Handler()));
new AfterAddNode());
addGroupRunnable.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -701,7 +706,7 @@ public class GroupActivity extends ListNodesActivity
App.getDB(),
oldGroupToUpdate,
updateGroup,
new AfterUpdateNode(new Handler()));
new AfterUpdateNode());
updateGroupRunnable.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
@@ -715,9 +720,6 @@ public class GroupActivity extends ListNodesActivity
}
class AfterAddNode extends AfterActionNodeOnFinish {
AfterAddNode(Handler handler) {
super(handler);
}
public void run(PwNode oldNode, PwNode newNode) {
super.run();
@@ -736,9 +738,6 @@ public class GroupActivity extends ListNodesActivity
}
class AfterUpdateNode extends AfterActionNodeOnFinish {
AfterUpdateNode(Handler handler) {
super(handler);
}
public void run(PwNode oldNode, PwNode newNode) {
super.run();
@@ -756,25 +755,19 @@ public class GroupActivity extends ListNodesActivity
}
}
class AfterDeleteNode extends OnFinishRunnable {
private PwNode pwNode;
AfterDeleteNode(Handler handler, PwNode pwNode) {
super(handler);
this.pwNode = pwNode;
}
class AfterDeleteNode extends AfterActionNodeOnFinish {
@Override
public void run() {
public void run(PwNode oldNode, PwNode newNode) {
super.run();
runOnUiThread(() -> {
if ( mSuccess) {
if (listNodesFragment != null)
listNodesFragment.removeNode(pwNode);
listNodesFragment.removeNode(oldNode);
PwGroup parent = pwNode.getParent();
PwGroup parent = oldNode.getParent();
Database db = App.getDB();
PwDatabase database = db.getPwDatabase();
if (db.isRecycleBinAvailable() &&

View File

@@ -0,0 +1,42 @@
package com.kunzisoft.keepass.database.action;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
public abstract class ActionDatabaseRunnable extends RunnableOnFinish {
protected Database mDb;
protected Context mContext;
protected boolean mDontSave;
public ActionDatabaseRunnable(Context context, Database db, OnFinishRunnable finish, boolean dontSave) {
super(finish);
this.mDb = db;
this.mContext = context;
this.mDontSave = dontSave;
this.mFinish = new AfterActionRunnable(finish);
}
@Override
public void run() {
// Commit to disk
SaveDatabaseRunnable save = new SaveDatabaseRunnable(mContext, mDb, mFinish, mDontSave);
save.run();
}
abstract protected void onFinish(boolean success);
private class AfterActionRunnable extends OnFinishRunnable {
AfterActionRunnable(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
onFinish(mSuccess);
}
}
}

View File

@@ -30,77 +30,56 @@ import com.kunzisoft.keepass.utils.UriUtil;
import java.io.IOException;
import java.io.InputStream;
public class AssignPasswordInDBRunnable extends RunnableOnFinish {
public class AssignPasswordInDBRunnable extends ActionDatabaseRunnable {
private String mPassword;
private Uri mKeyfile;
private Database mDb;
private boolean mDontSave;
private Context ctx;
private byte[] mBackupKey;
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish) {
this(ctx, db, password, keyfile, finish, false);
}
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish, boolean dontSave) {
super(finish);
super(ctx, db, finish, dontSave);
mDb = db;
mPassword = password;
mKeyfile = keyfile;
mDontSave = dontSave;
this.ctx = ctx;
this.mPassword = password;
this.mKeyfile = keyfile;
}
@Override
public void run() {
PwDatabase pm = mDb.getPwDatabase();
byte[] backupKey = new byte[pm.getMasterKey().length];
System.arraycopy(pm.getMasterKey(), 0, backupKey, 0, backupKey.length);
mBackupKey = new byte[pm.getMasterKey().length];
System.arraycopy(pm.getMasterKey(), 0, mBackupKey, 0, mBackupKey.length);
// Set key
try {
InputStream is = UriUtil.getUriInputStream(ctx, mKeyfile);
InputStream is = UriUtil.getUriInputStream(mContext, mKeyfile);
pm.retrieveMasterKey(mPassword, is);
} catch (InvalidKeyFileException e) {
erase(backupKey);
erase(mBackupKey);
finish(false, e.getMessage());
return;
} catch (IOException e) {
erase(backupKey);
erase(mBackupKey);
finish(false, e.getMessage());
return;
}
// Save Database
mFinish = new AfterSave(backupKey, mFinish);
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run();
super.run();
}
private class AfterSave extends OnFinishRunnable {
private byte[] mBackup;
public AfterSave(byte[] backup, OnFinishRunnable finish) {
super(finish);
mBackup = backup;
}
@Override
public void run() {
if ( ! mSuccess ) {
// Erase the current master key
erase(mDb.getPwDatabase().getMasterKey());
mDb.getPwDatabase().setMasterKey(mBackup);
}
super.run();
}
}
@Override
protected void onFinish(boolean success) {
if (!success) {
// Erase the current master key
erase(mDb.getPwDatabase().getMasterKey());
mDb.getPwDatabase().setMasterKey(mBackupKey);
}
}
/** Overwrite the array as soon as we don't need it to avoid keeping the extra data in memory
* @param array

View File

@@ -56,7 +56,7 @@ public class CreateDBRunnable extends RunnableOnFinish {
App.clearShutdown();
// Commit changes
SaveDBRunnable save = new SaveDBRunnable(ctx, db, mFinish, mDontSave);
SaveDatabaseRunnable save = new SaveDatabaseRunnable(ctx, db, mFinish, mDontSave);
mFinish = null;
save.run();
}

View File

@@ -1,103 +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.database.action;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
/** Task to delete entries
* @author bpellin
*
*/
public class DeleteEntryRunnable extends RunnableOnFinish {
private Database mDb;
private PwEntry mEntry;
private boolean mDontSave;
private Context ctx;
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
this(ctx, db, entry, finish, false);
}
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
super(finish);
this.mDb = db;
this.mEntry = entry;
this.mDontSave = dontSave;
this.ctx = ctx;
}
@Override
public void run() {
PwGroup parent = mEntry.getParent();
// Remove Entry from parent
boolean recycle = mDb.canRecycle(mEntry);
if (recycle) {
mDb.recycle(mEntry);
}
else {
mDb.deleteEntry(mEntry);
}
// Save
mFinish = new AfterDelete(mFinish, parent, mEntry, recycle);
// Commit database
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDelete extends OnFinishRunnable {
private PwGroup mParent;
private PwEntry mEntry;
private boolean recycled;
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwEntry entry, boolean r) {
super(finish);
mParent = parent;
mEntry = entry;
recycled = r;
}
@Override
public void run() {
if ( !mSuccess ) {
if (recycled) {
mDb.undoRecycle(mEntry, mParent);
}
else {
mDb.undoDeleteEntry(mEntry, mParent);
}
}
// TODO Callback after delete entry
super.run();
}
}
}

View File

@@ -1,125 +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.database.action;
import android.content.Context;
import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
import java.util.ArrayList;
import java.util.List;
public class DeleteGroupRunnable extends RunnableOnFinish {
private Context mContext;
private Database mDb;
private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
private boolean mDontSave;
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish) {
super(finish);
setMembers(ctx, db, group, false);
}
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish, boolean dontSave) {
super(finish);
setMembers(ctx, db, group, dontSave);
}
private void setMembers(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, boolean dontSave) {
mDb = db;
mGroup = group;
mContext = ctx;
mDontSave = dontSave;
}
@Override
public void run() {
PwGroup parent = mGroup.getParent();
// Remove Group from parent
boolean recycle = mDb.canRecycle(mGroup);
if (recycle) {
mDb.recycle(mGroup);
}
else {
// TODO tests
// Remove child entries
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods
for ( int i = 0; i < childEnt.size(); i++ ) {
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++ ) {
DeleteGroupRunnable task = new DeleteGroupRunnable(mContext, mDb, childGrp.get(i), null, true);
task.run();
}
mDb.deleteGroup(mGroup);
// Remove from PwDatabaseV3
// TODO ENcapsulate
mDb.getPwDatabase().getGroups().remove(mGroup);
}
// Save
mFinish = new AfterDelete(mFinish, parent, mGroup, recycle);
// Commit Database
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDelete extends OnFinishRunnable {
private PwGroup mParent;
private PwGroup mGroup;
private boolean recycled;
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
super(finish);
this.mParent = parent;
this.mGroup = mGroup;
this.recycled = recycle;
}
public void run() {
if ( !mSuccess ) {
if (recycled) {
mDb.undoRecycle(mGroup, mParent);
}
else {
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
App.setShutdown();
// TODO TEST pm.undoDeleteGroup(mGroup, mParent);
}
}
// TODO Callback after delete group
super.run();
}
}
}

View File

@@ -24,6 +24,7 @@ import android.net.Uri;
import java.io.Serializable;
public class FileOnFinishRunnable extends OnFinishRunnable implements Serializable {
private Uri mFilename = null;
protected FileOnFinishRunnable mOnFinish;

View File

@@ -83,4 +83,19 @@ public class OnFinishRunnable implements Runnable {
}
}
public boolean isSuccess() {
return mSuccess;
}
public void setSuccess(boolean mSuccess) {
this.mSuccess = mSuccess;
}
public String getMessage() {
return mMessage;
}
public void setMessage(String mMessage) {
this.mMessage = mMessage;
}
}

View File

@@ -26,13 +26,13 @@ import com.kunzisoft.keepass.database.exception.PwDbOutputException;
import java.io.IOException;
public class SaveDBRunnable extends RunnableOnFinish {
public class SaveDatabaseRunnable extends RunnableOnFinish {
private Context mCtx;
private Database mDb;
private boolean mDontSave;
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish, boolean dontSave) {
public SaveDatabaseRunnable(Context ctx, Database db, OnFinishRunnable finish, boolean dontSave) {
super(finish);
this.mDb = db;
@@ -40,7 +40,7 @@ public class SaveDBRunnable extends RunnableOnFinish {
this.mCtx = ctx;
}
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish) {
public SaveDatabaseRunnable(Context ctx, Database db, OnFinishRunnable finish) {
this(ctx, db, finish, false);
}

View File

@@ -0,0 +1,32 @@
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.action.ActionDatabaseRunnable;
abstract class ActionNodeDatabaseRunnable extends ActionDatabaseRunnable {
private AfterActionNodeOnFinish callbackRunnable;
public ActionNodeDatabaseRunnable(Context context, Database db, AfterActionNodeOnFinish finish, boolean dontSave) {
super(context, db, finish, dontSave);
this.callbackRunnable = finish;
}
/**
* Callback method who return the node(s) modified after an action
* - Add : @param oldNode NULL, @param newNode CreatedNode
* - Copy : @param oldNode NodeToCopy, @param newNode NodeCopied
* - Delete : @param oldNode NodeToDelete, @param NULL
* - Move : @param oldNode NULL, @param NodeToMove
* - Update : @param oldNode NodeToUpdate, @param NodeUpdated
*/
protected void callbackNodeAction(boolean success, PwNode oldNode, PwNode newNode) {
if (callbackRunnable != null) {
callbackRunnable.setSuccess(success);
callbackRunnable.run(oldNode, newNode);
}
}
}

View File

@@ -17,57 +17,40 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
public class AddEntryRunnable extends RunnableOnFinish {
public class AddEntryRunnable extends ActionNodeDatabaseRunnable {
protected Database mDb;
private PwEntry mEntry;
private Context ctx;
private boolean mDontSave;
private PwEntry mNewEntry;
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
this(ctx, db, entry, finish, false);
public AddEntryRunnable(Context ctx, Database db, PwEntry entryToAdd, AfterActionNodeOnFinish finish) {
this(ctx, db, entryToAdd, finish, false);
}
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
super(finish);
public AddEntryRunnable(Context ctx, Database db, PwEntry entryToAdd, AfterActionNodeOnFinish finish, boolean dontSave) {
super(ctx, db, finish, dontSave);
this.mDb = db;
this.mEntry = entry;
this.ctx = ctx;
this.mDontSave = dontSave;
this.mFinish = new AfterAdd(mFinish);
this.mNewEntry = entryToAdd;
}
@Override
public void run() {
mDb.addEntryTo(mEntry, mEntry.getParent());
mDb.addEntryTo(mNewEntry, mNewEntry.getParent());
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run();
super.run();
}
private class AfterAdd extends OnFinishRunnable {
AfterAdd(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
if ( !mSuccess ) {
mDb.removeEntryFrom(mEntry, mEntry.getParent());
}
// TODO if add entry callback
super.run();
@Override
protected void onFinish(boolean success) {
if ( !success ) {
mDb.removeEntryFrom(mNewEntry, mNewEntry.getParent());
}
callbackNodeAction(success, null, mNewEntry);
}
}

View File

@@ -17,34 +17,25 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwGroup;
public class AddGroupRunnable extends RunnableOnFinish {
public class AddGroupRunnable extends ActionNodeDatabaseRunnable {
protected Database mDb;
private PwGroup mNewGroup;
private Context ctx;
private boolean mDontSave;
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode) {
this(ctx, db, newGroup, afterAddNode, false);
}
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode,
boolean dontSave) {
super(afterAddNode);
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
super(ctx, db, afterAddNode, dontSave);
this.mDb = db;
this.mNewGroup = newGroup;
this.mDontSave = dontSave;
this.ctx = ctx;
this.mFinish = new AfterAdd(mFinish);
}
@Override
@@ -52,28 +43,14 @@ public class AddGroupRunnable extends RunnableOnFinish {
mDb.addGroupTo(mNewGroup, mNewGroup.getParent());
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run();
super.run();
}
private class AfterAdd extends OnFinishRunnable {
AfterAdd(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
if ( !mSuccess ) {
mDb.removeGroupFrom(mNewGroup, mNewGroup.getParent());
}
// TODO Better callback
AfterActionNodeOnFinish afterAddNode =
(AfterActionNodeOnFinish) super.mOnFinish;
afterAddNode.mSuccess = mSuccess;
afterAddNode.mMessage = mMessage;
afterAddNode.run(null, mNewGroup);
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
mDb.removeGroupFrom(mNewGroup, mNewGroup.getParent());
}
callbackNodeAction(success, null, mNewGroup);
}
}

View File

@@ -17,16 +17,20 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.os.Handler;
import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import javax.annotation.Nullable;
public abstract class AfterActionNodeOnFinish extends OnFinishRunnable {
public AfterActionNodeOnFinish(Handler handler) {
super(handler);
public AfterActionNodeOnFinish() {
super(new Handler());
}
public abstract void run(PwNode oldNode, PwNode newNode);
public abstract void run(@Nullable PwNode oldNode, @Nullable PwNode newNode);
}

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import android.util.Log;
@@ -26,31 +26,23 @@ import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
public class CopyEntryRunnable extends RunnableOnFinish {
public class CopyEntryRunnable extends ActionNodeDatabaseRunnable {
private static final String TAG = CopyEntryRunnable.class.getName();
private Database mDb;
private PwEntry mEntryToCopy;
private PwEntry mEntryCopied;
private PwGroup mNewParent;
private Context mContext;
private boolean mDontSave;
public CopyEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
this(context, db, oldE, newParent, afterAddNode, false);
}
public CopyEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
super(afterAddNode);
super(context, db, afterAddNode, dontSave);
this.mDb = db;
this.mEntryToCopy = oldE;
this.mNewParent = newParent;
this.mContext = context;
this.mDontSave = dontSave;
this.mFinish = new AfterCopy(afterAddNode);
}
@Override
@@ -62,37 +54,22 @@ public class CopyEntryRunnable extends RunnableOnFinish {
mEntryCopied.touch(true, true);
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
save.run();
super.run();
} else {
Log.e(TAG, "Unable to create a copy of the entry");
}
}
private class AfterCopy extends OnFinishRunnable {
AfterCopy(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
if ( !mSuccess ) {
// If we fail to save, try to delete the copy
try {
mDb.deleteEntry(mEntryCopied);
} catch (Exception e) {
Log.i(TAG, "Unable to delete the copied entry");
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
// If we fail to save, try to delete the copy
try {
mDb.deleteEntry(mEntryCopied);
} catch (Exception e) {
Log.i(TAG, "Unable to delete the copied entry");
}
// TODO Better callback
AfterActionNodeOnFinish afterAddNode =
(AfterActionNodeOnFinish) super.mOnFinish;
afterAddNode.mSuccess = mSuccess;
afterAddNode.mMessage = mMessage;
afterAddNode.run(null, mEntryCopied);
super.run();
}
callbackNodeAction(success, mEntryToCopy, mEntryCopied);
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
public class DeleteEntryRunnable extends ActionNodeDatabaseRunnable {
private PwEntry mEntryToDelete;
private PwGroup mParent;
private boolean mRecycle;
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, AfterActionNodeOnFinish finish) {
this(ctx, db, entry, finish, false);
}
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, AfterActionNodeOnFinish finish, boolean dontSave) {
super(ctx, db, finish, dontSave);
this.mEntryToDelete = entry;
}
@Override
public void run() {
mParent = mEntryToDelete.getParent();
// Remove Entry from parent
mRecycle = mDb.canRecycle(mEntryToDelete);
if (mRecycle) {
mDb.recycle(mEntryToDelete);
}
else {
mDb.deleteEntry(mEntryToDelete);
}
// Commit database
super.run();
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
if (mRecycle) {
mDb.undoRecycle(mEntryToDelete, mParent);
}
else {
mDb.undoDeleteEntry(mEntryToDelete, mParent);
}
}
callbackNodeAction(success, mEntryToDelete, null);
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
import java.util.ArrayList;
import java.util.List;
public class DeleteGroupRunnable extends ActionNodeDatabaseRunnable {
private PwGroup<PwGroup, PwGroup, PwEntry> mGroupToDelete;
private PwGroup mParent;
private boolean mRecycle;
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, AfterActionNodeOnFinish finish) {
this(ctx, db, group, finish, false);
}
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, AfterActionNodeOnFinish finish, boolean dontSave) {
super(ctx, db, finish, dontSave);
mGroupToDelete = group;
}
@Override
public void run() {
mParent = mGroupToDelete.getParent();
// Remove Group from parent
mRecycle = mDb.canRecycle(mGroupToDelete);
if (mRecycle) {
mDb.recycle(mGroupToDelete);
}
else {
// TODO tests
// Remove child entries
List<PwEntry> childEnt = new ArrayList<>(mGroupToDelete.getChildEntries()); // TODO new Methods
for ( int i = 0; i < childEnt.size(); i++ ) {
DeleteEntryRunnable task = new DeleteEntryRunnable(mContext, mDb, childEnt.get(i), null, true);
task.run();
}
// Remove child groups
List<PwGroup> childGrp = new ArrayList<>(mGroupToDelete.getChildGroups());
for ( int i = 0; i < childGrp.size(); i++ ) {
DeleteGroupRunnable task = new DeleteGroupRunnable(mContext, mDb, childGrp.get(i), null, true);
task.run();
}
mDb.deleteGroup(mGroupToDelete);
// Remove from PwDatabaseV3
// TODO ENcapsulate
mDb.getPwDatabase().getGroups().remove(mGroupToDelete);
}
// Commit Database
super.run();
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
if (mRecycle) {
mDb.undoRecycle(mGroupToDelete, mParent);
}
else {
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
App.setShutdown();
// TODO TEST pm.undoDeleteGroup(mGroup, mParent);
}
}
callbackNodeAction(success, mGroupToDelete, null);
}
}

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import android.util.Log;
@@ -26,31 +26,23 @@ import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup;
public class MoveEntryRunnable extends RunnableOnFinish {
public class MoveEntryRunnable extends ActionNodeDatabaseRunnable {
private static final String TAG = MoveEntryRunnable.class.getName();
private Database mDb;
private PwEntry mEntryToMove;
private PwGroup mOldParent;
private PwGroup mNewParent;
private Context mContext;
private boolean mDontSave;
public MoveEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
this(context, db, oldE, newParent, afterAddNode, false);
}
public MoveEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
super(afterAddNode);
super(context, db, afterAddNode, dontSave);
this.mDb = db;
this.mEntryToMove = oldE;
this.mNewParent = newParent;
this.mContext = context;
this.mDontSave = dontSave;
this.mFinish = new AfterMove(afterAddNode);
}
@Override
@@ -64,37 +56,22 @@ public class MoveEntryRunnable extends RunnableOnFinish {
mEntryToMove.touch(true, true);
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
save.run();
super.run();
} else {
Log.e(TAG, "Unable to create a copy of the entry");
}
}
private class AfterMove extends OnFinishRunnable {
AfterMove(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
if ( !mSuccess ) {
// If we fail to save, try to remove in the first place
try {
mDb.moveEntry(mEntryToMove, mOldParent);
} catch (Exception e) {
Log.i(TAG, "Unable to replace the entry");
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
// If we fail to save, try to remove in the first place
try {
mDb.moveEntry(mEntryToMove, mOldParent);
} catch (Exception e) {
Log.i(TAG, "Unable to replace the entry");
}
// TODO Better callback
AfterActionNodeOnFinish afterAddNode =
(AfterActionNodeOnFinish) super.mOnFinish;
afterAddNode.mSuccess = mSuccess;
afterAddNode.mMessage = mMessage;
afterAddNode.run(null, mEntryToMove);
super.run();
}
callbackNodeAction(success, null, mEntryToMove);
}
}

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import android.util.Log;
@@ -25,31 +25,23 @@ import android.util.Log;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwGroup;
public class MoveGroupRunnable extends RunnableOnFinish {
public class MoveGroupRunnable extends ActionNodeDatabaseRunnable {
private static final String TAG = MoveGroupRunnable.class.getName();
private Database mDb;
private PwGroup mGroupToMove;
private PwGroup mOldParent;
private PwGroup mNewParent;
private Context mContext;
private boolean mDontSave;
public MoveGroupRunnable(Context context, Database db, PwGroup groupToMove, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
this(context, db, groupToMove, newParent, afterAddNode, false);
}
public MoveGroupRunnable(Context context, Database db, PwGroup groupToMove, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
super(afterAddNode);
super(context, db, afterAddNode, dontSave);
this.mDb = db;
this.mGroupToMove = groupToMove;
this.mNewParent = newParent;
this.mContext = context;
this.mDontSave = dontSave;
this.mFinish = new AfterMove(afterAddNode);
}
@Override
@@ -64,8 +56,7 @@ public class MoveGroupRunnable extends RunnableOnFinish {
mGroupToMove.touch(true, true);
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
save.run();
super.run();
} else {
Log.e(TAG, "Unable to create a copy of the group");
}
@@ -77,30 +68,16 @@ public class MoveGroupRunnable extends RunnableOnFinish {
}
}
private class AfterMove extends OnFinishRunnable {
AfterMove(OnFinishRunnable finish) {
super(finish);
}
@Override
public void run() {
if ( !mSuccess ) {
// If we fail to save, try to move in the first place
try {
mDb.moveGroup(mGroupToMove, mOldParent);
} catch (Exception e) {
Log.i(TAG, "Unable to replace the group");
}
}
// TODO Better callback
AfterActionNodeOnFinish afterAddNode =
(AfterActionNodeOnFinish) super.mOnFinish;
afterAddNode.mSuccess = mSuccess;
afterAddNode.mMessage = mMessage;
afterAddNode.run(null, mGroupToMove);
super.run();
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
// If we fail to save, try to move in the first place
try {
mDb.moveGroup(mGroupToMove, mOldParent);
} catch (Exception e) {
Log.i(TAG, "Unable to replace the group");
}
}
callbackNodeAction(success, null, mGroupToMove);
}
}

View File

@@ -17,68 +17,47 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry;
public class UpdateEntryRunnable extends RunnableOnFinish {
public class UpdateEntryRunnable extends ActionNodeDatabaseRunnable {
private Database mDb;
private PwEntry mOldE;
private PwEntry mNewE;
private Context ctx;
private boolean mDontSave;
private PwEntry mOldEntry;
private PwEntry mNewEntry;
private PwEntry mBackupEntry;
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish) {
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, AfterActionNodeOnFinish finish) {
this(ctx, db, oldE, newE, finish, false);
}
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish, boolean dontSave) {
super(finish);
this.mDb = db;
this.mOldE = oldE;
this.mNewE = newE;
this.ctx = ctx;
this.mDontSave = dontSave;
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, AfterActionNodeOnFinish finish, boolean dontSave) {
super(ctx, db, finish, dontSave);
this.mOldEntry = oldE;
this.mNewEntry = newE;
// Keep backup of original values in case save fails
PwEntry backup;
backup = mOldE.clone();
mFinish = new AfterUpdate(backup, finish);
this.mBackupEntry = mOldEntry.clone();
}
@Override
public void run() {
// Update entry with new values
mDb.updateEntry(mOldE, mNewE);
mOldE.touch(true, true);
mDb.updateEntry(mOldEntry, mNewEntry);
mOldEntry.touch(true, true);
// Commit to disk
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run();
super.run();
}
private class AfterUpdate extends OnFinishRunnable {
private PwEntry mBackup;
AfterUpdate(PwEntry backup, OnFinishRunnable finish) {
super(finish);
mBackup = backup;
}
@Override
public void run() {
if ( !mSuccess ) {
// If we fail to save, back out changes to global structure
mDb.updateEntry(mOldE, mBackup);
}
// TODO Callback for update entry
super.run();
}
}
@Override
protected void onFinish(boolean success) {
if ( !success ) {
// If we fail to save, back out changes to global structure
mDb.updateEntry(mOldEntry, mBackupEntry);
}
callbackNodeAction(success, mOldEntry, mNewEntry);
}
}

View File

@@ -17,39 +17,30 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.database.action;
package com.kunzisoft.keepass.database.action.node;
import android.content.Context;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwGroup;
public class UpdateGroupRunnable extends RunnableOnFinish {
public class UpdateGroupRunnable extends ActionNodeDatabaseRunnable {
private Database mDb;
private PwGroup mOldGroup;
private PwGroup mNewGroup;
private Context ctx;
private boolean mDontSave;
private PwGroup mBackupGroup;
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish) {
this(ctx, db, oldGroup, newGroup, finish, false);
}
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish, boolean dontSave) {
super(finish);
super(ctx, db, finish, dontSave);
this.mDb = db;
this.mOldGroup = oldGroup;
this.mNewGroup = newGroup;
this.ctx = ctx;
this.mDontSave = dontSave;
// Keep backup of original values in case save fails
PwGroup backup;
backup = mOldGroup.clone();
this.mFinish = new AfterUpdate(backup, finish);
this.mBackupGroup = mOldGroup.clone();
}
@Override
@@ -59,30 +50,15 @@ public class UpdateGroupRunnable extends RunnableOnFinish {
mOldGroup.touch(true, true);
// Commit to disk
new SaveDBRunnable(ctx, mDb, mFinish, mDontSave).run();
super.run();
}
private class AfterUpdate extends OnFinishRunnable {
private PwGroup mBackup;
AfterUpdate(PwGroup backup, OnFinishRunnable finish) {
super(finish);
mBackup = backup;
}
@Override
public void run() {
if ( !mSuccess ) {
// If we fail to save, back out changes to global structure
mDb.updateGroup(mOldGroup, mBackup);
}
// TODO Better callback
AfterActionNodeOnFinish afterActionNodeOnFinish =
(AfterActionNodeOnFinish) super.mOnFinish;
afterActionNodeOnFinish.mSuccess = mSuccess;
afterActionNodeOnFinish.mMessage = mMessage;
afterActionNodeOnFinish.run(mOldGroup, mNewGroup);
@Override
protected void onFinish(boolean success) {
if ( !success ) {
// If we fail to save, back out changes to global structure
mDb.updateGroup(mOldGroup, mBackupGroup);
}
callbackNodeAction(success, mOldGroup, mNewGroup);
}
}

View File

@@ -24,7 +24,7 @@ import android.view.View;
import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.database.action.SaveDBRunnable;
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable;
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
@@ -47,15 +47,15 @@ public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputP
assert getActivity() != null;
if (database != null && afterSaveDatabase != null) {
SaveDBRunnable saveDBRunnable = new SaveDBRunnable(getContext(),
SaveDatabaseRunnable saveDatabaseRunnable = new SaveDatabaseRunnable(getContext(),
database,
afterSaveDatabase);
saveDBRunnable.setUpdateProgressTaskStatus(
saveDatabaseRunnable.setUpdateProgressTaskStatus(
new UpdateProgressTaskStatus(getContext(),
SaveDatabaseProgressTaskDialogFragment.start(
getActivity().getSupportFragmentManager())
));
new Thread(saveDBRunnable).start();
new Thread(saveDatabaseRunnable).start();
}
}
}