Merge branch 'feature/RefactorProgress' into develop #98

This commit is contained in:
J-Jamet
2018-05-02 13:49:56 +02:00
44 changed files with 772 additions and 513 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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());
});
}
}

View File

@@ -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;

View File

@@ -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());
});
}
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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";

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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());
});
}
}
}

View File

@@ -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";

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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"

View 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>

View File

@@ -0,0 +1,4 @@
* Upgrade translations
* Fix classic dark theme
* Add Material Icon Pack to the Free version
* Fix bugs

View 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