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) KeepassDX (2.5.0.0beta9)
* Education Screens to learn how to use the app * Education Screens to learn how to use the app
* New designs * New designs

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.kunzisoft.keepass" applicationId "com.kunzisoft.keepass"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 27 targetSdkVersion 27
versionCode = 9 versionCode = 10
versionName = "2.5.0.0beta9" versionName = "2.5.0.0beta10"
multiDexEnabled true multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests" 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.PwEntry;
import com.kunzisoft.keepass.database.PwEntryV3; import com.kunzisoft.keepass.database.PwEntryV3;
import com.kunzisoft.keepass.database.PwGroup; 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; import com.kunzisoft.keepass.search.SearchDbHelper;
public class DeleteEntry extends AndroidTestCase { public class DeleteEntry extends AndroidTestCase {
@@ -60,7 +60,7 @@ public class DeleteEntry extends AndroidTestCase {
assertNotNull("Could not find group1", group1); assertNotNull("Could not find group1", group1);
// Delete the group // Delete the group
DeleteGroup task = new DeleteGroup(null, db, group1, null, true); DeleteGroupRunnable task = new DeleteGroupRunnable(null, db, group1, null, true);
task.run(); task.run();
// Verify the entries were deleted // 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.PwGroup;
import com.kunzisoft.keepass.database.PwGroupId; import com.kunzisoft.keepass.database.PwGroupId;
import com.kunzisoft.keepass.database.PwIconStandard; import com.kunzisoft.keepass.database.PwIconStandard;
import com.kunzisoft.keepass.database.edit.AddEntry; import com.kunzisoft.keepass.database.action.AddEntryRunnable;
import com.kunzisoft.keepass.database.edit.OnFinish; import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.database.edit.RunnableOnFinish; import com.kunzisoft.keepass.database.action.RunnableOnFinish;
import com.kunzisoft.keepass.database.edit.UpdateEntry; import com.kunzisoft.keepass.database.action.UpdateEntryRunnable;
import com.kunzisoft.keepass.database.security.ProtectedString; import com.kunzisoft.keepass.database.security.ProtectedString;
import com.kunzisoft.keepass.dialogs.GeneratePasswordDialogFragment; import com.kunzisoft.keepass.dialogs.GeneratePasswordDialogFragment;
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment; import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
import com.kunzisoft.keepass.icons.IconPackChooser; import com.kunzisoft.keepass.icons.IconPackChooser;
import com.kunzisoft.keepass.settings.PreferencesUtil; 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.MenuUtil;
import com.kunzisoft.keepass.utils.Types; import com.kunzisoft.keepass.utils.Types;
import com.kunzisoft.keepass.utils.Util; import com.kunzisoft.keepass.utils.Util;
@@ -249,16 +250,21 @@ public class EntryEditActivity extends LockingHideActivity
} }
mCallbackNewEntry = populateNewEntry(); mCallbackNewEntry = populateNewEntry();
OnFinish onFinish = new AfterSave(); // Open a progress dialog and save entry
OnFinishRunnable onFinish = new AfterSave();
EntryEditActivity act = EntryEditActivity.this; EntryEditActivity act = EntryEditActivity.this;
RunnableOnFinish task; RunnableOnFinish task;
if ( mIsNew ) { if ( mIsNew ) {
task = new AddEntry(act, App.getDB(), mCallbackNewEntry, onFinish); task = new AddEntryRunnable(act, App.getDB(), mCallbackNewEntry, onFinish);
} else { } 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); task.setUpdateProgressTaskStatus(
pt.run(); 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() { AfterSave() {
super(new Handler()); super(new Handler());
@@ -562,11 +568,15 @@ public class EntryEditActivity extends LockingHideActivity
@Override @Override
public void run() { public void run() {
if ( mSuccess ) { runOnUiThread(() -> {
finish(); if ( mSuccess ) {
} else { finish();
displayMessage(EntryEditActivity.this); } 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.PwIconStandard;
import com.kunzisoft.keepass.database.PwNode; import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.SortNodeEnum; import com.kunzisoft.keepass.database.SortNodeEnum;
import com.kunzisoft.keepass.database.edit.AddGroup; import com.kunzisoft.keepass.database.action.AddGroupRunnable;
import com.kunzisoft.keepass.database.edit.DeleteEntry; import com.kunzisoft.keepass.database.action.DeleteEntryRunnable;
import com.kunzisoft.keepass.database.edit.DeleteGroup; import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
import com.kunzisoft.keepass.database.edit.UpdateGroup; import com.kunzisoft.keepass.database.action.UpdateGroupRunnable;
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment; import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment; import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment;
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment; 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.icons.IconPackChooser;
import com.kunzisoft.keepass.search.SearchResultsActivity; import com.kunzisoft.keepass.search.SearchResultsActivity;
import com.kunzisoft.keepass.settings.PreferencesUtil; 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; import com.kunzisoft.keepass.view.AddNodeButtonView;
public class GroupActivity extends ListNodesActivity public class GroupActivity extends ListNodesActivity
@@ -435,19 +436,27 @@ public class GroupActivity extends ListNodesActivity
private void deleteEntry(PwEntry entry) { private void deleteEntry(PwEntry entry) {
Handler handler = new Handler(); Handler handler = new Handler();
DeleteEntry task = new DeleteEntry(this, App.getDB(), entry, DeleteEntryRunnable task = new DeleteEntryRunnable(this, App.getDB(), entry,
new AfterDeleteNode(handler, entry)); new AfterDeleteNode(handler, entry));
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database); task.setUpdateProgressTaskStatus(
pt.run(); new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
getSupportFragmentManager())
));
new Thread(task).start();
} }
private void deleteGroup(PwGroup group) { private void deleteGroup(PwGroup group) {
//TODO Verify trash recycle bin //TODO Verify trash recycle bin
Handler handler = new Handler(); Handler handler = new Handler();
DeleteGroup task = new DeleteGroup(this, App.getDB(), group, DeleteGroupRunnable task = new DeleteGroupRunnable(this, App.getDB(), group,
new AfterDeleteNode(handler, group)); new AfterDeleteNode(handler, group));
ProgressTask pt = new ProgressTask(this, task, R.string.saving_database); task.setUpdateProgressTaskStatus(
pt.run(); new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
getSupportFragmentManager())
));
new Thread(task).start();
} }
@Override @Override
@@ -548,16 +557,21 @@ public class GroupActivity extends ListNodesActivity
newGroup.setName(name); newGroup.setName(name);
try { try {
iconStandard = (PwIconStandard) icon; iconStandard = (PwIconStandard) icon;
} catch (Exception e) {} // TODO custom icon } catch (Exception ignored) {} // TODO custom icon
newGroup.setIcon(iconStandard); newGroup.setIcon(iconStandard);
new ProgressTask(this, // If group created save it in the database
new AddGroup(this, AddGroupRunnable addGroupRunnable = new AddGroupRunnable(this,
App.getDB(), App.getDB(),
newGroup, newGroup,
new AfterAddNode(new Handler())), new AfterAddNode(new Handler()));
R.string.saving_database) addGroupRunnable.setUpdateProgressTaskStatus(
.run(); new UpdateProgressTaskStatus(this,
SaveDatabaseProgressTaskDialogFragment.start(
getSupportFragmentManager())
));
new Thread(addGroupRunnable).start();
break; break;
case UPDATE: case UPDATE:
// If update add new elements // If update add new elements
@@ -566,20 +580,23 @@ public class GroupActivity extends ListNodesActivity
updateGroup.setName(name); updateGroup.setName(name);
try { try {
iconStandard = (PwIconStandard) icon; iconStandard = (PwIconStandard) icon;
} catch (Exception e) {} // TODO custom icon } catch (Exception ignored) {} // TODO custom icon
updateGroup.setIcon(iconStandard); updateGroup.setIcon(iconStandard);
mAdapter.removeNode(oldGroupToUpdate); 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; break;

View File

@@ -49,12 +49,13 @@ import com.kunzisoft.keepass.database.PwEntry;
import com.kunzisoft.keepass.database.PwGroup; import com.kunzisoft.keepass.database.PwGroup;
import com.kunzisoft.keepass.database.PwNode; import com.kunzisoft.keepass.database.PwNode;
import com.kunzisoft.keepass.database.SortNodeEnum; import com.kunzisoft.keepass.database.SortNodeEnum;
import com.kunzisoft.keepass.database.edit.AfterActionNodeOnFinish; import com.kunzisoft.keepass.database.action.AfterActionNodeOnFinish;
import com.kunzisoft.keepass.database.edit.OnFinish; import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment; import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
import com.kunzisoft.keepass.dialogs.SortDialogFragment; import com.kunzisoft.keepass.dialogs.SortDialogFragment;
import com.kunzisoft.keepass.password.AssignPasswordHelper; import com.kunzisoft.keepass.password.AssignPasswordHelper;
import com.kunzisoft.keepass.settings.PreferencesUtil; import com.kunzisoft.keepass.settings.PreferencesUtil;
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
import com.kunzisoft.keepass.tasks.UIToastTask; import com.kunzisoft.keepass.tasks.UIToastTask;
import com.kunzisoft.keepass.utils.MenuUtil; import com.kunzisoft.keepass.utils.MenuUtil;
@@ -307,11 +308,16 @@ public abstract class ListNodesActivity extends LockingActivity
public void run(PwNode oldNode, PwNode newNode) { public void run(PwNode oldNode, PwNode newNode) {
super.run(); super.run();
if (mSuccess) {
mAdapter.addNode(newNode); runOnUiThread(() -> {
} else { if (mSuccess) {
displayMessage(ListNodesActivity.this); 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) { public void run(PwNode oldNode, PwNode newNode) {
super.run(); super.run();
if (mSuccess) {
mAdapter.updateNode(oldNode, newNode); runOnUiThread(() -> {
} else { if (mSuccess) {
displayMessage(ListNodesActivity.this); mAdapter.updateNode(oldNode, newNode);
} } else {
displayMessage(ListNodesActivity.this);
}
SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
});
} }
} }
class AfterDeleteNode extends OnFinish { class AfterDeleteNode extends OnFinishRunnable {
private PwNode pwNode; private PwNode pwNode;
AfterDeleteNode(Handler handler, PwNode pwNode) { AfterDeleteNode(Handler handler, PwNode pwNode) {
@@ -340,27 +351,33 @@ public abstract class ListNodesActivity extends LockingActivity
@Override @Override
public void run() { public void run() {
if ( mSuccess) { super.run();
mAdapter.removeNode(pwNode);
PwGroup parent = pwNode.getParent(); runOnUiThread(() -> {
Database db = App.getDB(); if ( mSuccess) {
PwDatabase database = db.getPwDatabase(); mAdapter.removeNode(pwNode);
if (db.isRecycleBinAvailable() && PwGroup parent = pwNode.getParent();
db.isRecycleBinEnabled()) { Database db = App.getDB();
PwGroup recycleBin = database.getRecycleBin(); PwDatabase database = db.getPwDatabase();
// Add trash if it doesn't exists if (db.isRecycleBinAvailable() &&
if (parent.equals(recycleBin) db.isRecycleBinEnabled()) {
&& mCurrentGroup != null PwGroup recycleBin = database.getRecycleBin();
&& mCurrentGroup.getParent() == null // Add trash if it doesn't exists
&& !mCurrentGroup.equals(recycleBin)) { if (parent.equals(recycleBin)
mAdapter.addNode(parent); && 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)); SaveDatabaseProgressTaskDialogFragment.stop(getSupportFragmentManager());
App.setShutdown(); });
finish();
}
} }
} }
} }

View File

@@ -36,7 +36,7 @@ import com.kunzisoft.keepass.database.load.ImporterFactory;
import com.kunzisoft.keepass.database.save.PwDbOutput; import com.kunzisoft.keepass.database.save.PwDbOutput;
import com.kunzisoft.keepass.icons.IconDrawableFactory; import com.kunzisoft.keepass.icons.IconDrawableFactory;
import com.kunzisoft.keepass.search.SearchDbHelper; 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 com.kunzisoft.keepass.utils.UriUtil;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@@ -99,19 +99,11 @@ public class Database {
loaded = true; loaded = true;
} }
public void loadData(Context ctx, InputStream is, String password, InputStream keyInputStream) throws IOException, InvalidDBException { public void loadData(Context ctx, Uri uri, String password, Uri keyfile, ProgressTaskUpdater status) throws IOException, FileNotFoundException, 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 {
loadData(ctx, uri, password, keyfile, status, !Importer.DEBUG); 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; mUri = uri;
readOnly = false; readOnly = false;
if (uri.getScheme().equals("file")) { 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; InputStream is, kfIs;
try { try {
is = UriUtil.getUriInputStream(ctx, uri); 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 { 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 { private void loadData(Context ctx, InputStream is, String password, InputStream kfIs, ProgressTaskUpdater progressTaskUpdater, boolean debug, long roundsFix) 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 {
BufferedInputStream bis = new BufferedInputStream(is); BufferedInputStream bis = new BufferedInputStream(is);
if ( ! bis.markSupported() ) { if ( ! bis.markSupported() ) {
@@ -178,7 +166,7 @@ public class Database {
bis.reset(); // Return to the start 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 ) { if ( pm != null ) {
try { try {
switch (pm.getVersion()) { switch (pm.getVersion()) {
@@ -222,19 +210,23 @@ public class Database {
saveData(ctx, mUri); 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")) { if (uri.getScheme().equals("file")) {
String filename = uri.getPath(); String filename = uri.getPath();
File tempFile = new File(filename + ".tmp"); File tempFile = new File(filename + ".tmp");
FileOutputStream fos = new FileOutputStream(tempFile);
//BufferedOutputStream bos = new BufferedOutputStream(fos);
//PwDbV3Output pmo = new PwDbV3Output(pm, bos, App.getCalendar()); FileOutputStream fos = null;
PwDbOutput pmo = PwDbOutput.getInstance(pm, fos); try {
pmo.output(); fos = new FileOutputStream(tempFile);
//bos.flush(); PwDbOutput pmo = PwDbOutput.getInstance(pm, fos);
//bos.close(); if (pmo != null)
fos.close(); pmo.output();
} catch (Exception e) {
throw new IOException("Failed to store database.");
} finally {
if (fos != null)
fos.close();
}
// Force data to disk before continuing // Force data to disk before continuing
try { try {
@@ -250,16 +242,18 @@ public class Database {
} }
} }
else { else {
OutputStream os; OutputStream os = null;
try { try {
os = ctx.getContentResolver().openOutputStream(uri); os = ctx.getContentResolver().openOutputStream(uri);
PwDbOutput pmo = PwDbOutput.getInstance(pm, os);
if (pmo != null)
pmo.output();
} catch (Exception e) { } catch (Exception e) {
throw new IOException("Failed to store database."); 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; mUri = uri;
} }

View File

@@ -100,25 +100,6 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
return finalKey; 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 * Encrypt the master key a few times to make brute-force key-search harder
* @throws IOException * @throws IOException

View File

@@ -47,9 +47,13 @@ package com.kunzisoft.keepass.database;
import com.kunzisoft.keepass.crypto.keyDerivation.AesKdf; import com.kunzisoft.keepass.crypto.keyDerivation.AesKdf;
import com.kunzisoft.keepass.database.exception.InvalidKeyFileException; import com.kunzisoft.keepass.database.exception.InvalidKeyFileException;
import com.kunzisoft.keepass.stream.NullOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; 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 @Override
protected String getPasswordEncoding() { protected String getPasswordEncoding() {
return "ISO-8859-1"; return "ISO-8859-1";

View File

@@ -362,28 +362,6 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
return md.digest(fKey); 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 { public void makeFinalKey(byte[] masterSeed, KdfParameters kdfP) throws IOException {
makeFinalKey(masterSeed, kdfP, 0); makeFinalKey(masterSeed, kdfP, 0);
} }

View File

@@ -17,25 +17,25 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry; import com.kunzisoft.keepass.database.PwEntry;
public class AddEntry extends RunnableOnFinish { public class AddEntryRunnable extends RunnableOnFinish {
protected Database mDb; protected Database mDb;
private PwEntry mEntry; private PwEntry mEntry;
private Context ctx; private Context ctx;
private boolean mDontSave; 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); 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); super(finish);
this.mDb = db; this.mDb = db;
@@ -51,13 +51,13 @@ public class AddEntry extends RunnableOnFinish {
mDb.addEntryTo(mEntry, mEntry.getParent()); mDb.addEntryTo(mEntry, mEntry.getParent());
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterAdd extends OnFinish { private class AfterAdd extends OnFinishRunnable {
AfterAdd(OnFinish finish) { AfterAdd(OnFinishRunnable finish) {
super(finish); super(finish);
} }

View File

@@ -17,26 +17,26 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwGroup; import com.kunzisoft.keepass.database.PwGroup;
public class AddGroup extends RunnableOnFinish { public class AddGroupRunnable extends RunnableOnFinish {
protected Database mDb; protected Database mDb;
private PwGroup mNewGroup; private PwGroup mNewGroup;
private Context ctx; private Context ctx;
private boolean mDontSave; 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); this(ctx, db, newGroup, afterAddNode, false);
} }
public AddGroup(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode, public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode,
boolean dontSave) { boolean dontSave) {
super(afterAddNode); super(afterAddNode);
this.mDb = db; this.mDb = db;
@@ -52,13 +52,13 @@ public class AddGroup extends RunnableOnFinish {
mDb.addGroupTo(mNewGroup, mNewGroup.getParent()); mDb.addGroupTo(mNewGroup, mNewGroup.getParent());
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterAdd extends OnFinish { private class AfterAdd extends OnFinishRunnable {
AfterAdd(OnFinish finish) { AfterAdd(OnFinishRunnable finish) {
super(finish); super(finish);
} }

View File

@@ -17,13 +17,13 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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 android.os.Handler;
import com.kunzisoft.keepass.database.PwNode; import com.kunzisoft.keepass.database.PwNode;
public abstract class AfterActionNodeOnFinish extends OnFinish { public abstract class AfterActionNodeOnFinish extends OnFinishRunnable {
public AfterActionNodeOnFinish(Handler handler) { public AfterActionNodeOnFinish(Handler handler) {
super(handler); super(handler);
} }

View File

@@ -17,22 +17,20 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import android.content.DialogInterface;
import android.net.Uri; import android.net.Uri;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwDatabase; import com.kunzisoft.keepass.database.PwDatabase;
import com.kunzisoft.keepass.database.exception.InvalidKeyFileException; import com.kunzisoft.keepass.database.exception.InvalidKeyFileException;
import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper;
import com.kunzisoft.keepass.utils.UriUtil; import com.kunzisoft.keepass.utils.UriUtil;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
public class SetPassword extends RunnableOnFinish { public class AssignPasswordInDBRunnable extends RunnableOnFinish {
private String mPassword; private String mPassword;
private Uri mKeyfile; private Uri mKeyfile;
@@ -40,12 +38,12 @@ public class SetPassword extends RunnableOnFinish {
private boolean mDontSave; private boolean mDontSave;
private Context ctx; 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); 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); super(finish);
mDb = db; mDb = db;
@@ -55,16 +53,6 @@ public class SetPassword extends RunnableOnFinish {
this.ctx = ctx; 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 @Override
public void run() { public void run() {
PwDatabase pm = mDb.getPwDatabase(); PwDatabase pm = mDb.getPwDatabase();
@@ -88,14 +76,14 @@ public class SetPassword extends RunnableOnFinish {
// Save Database // Save Database
mFinish = new AfterSave(backupKey, mFinish); mFinish = new AfterSave(backupKey, mFinish);
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterSave extends OnFinish { private class AfterSave extends OnFinishRunnable {
private byte[] mBackup; private byte[] mBackup;
public AfterSave(byte[] backup, OnFinish finish) { public AfterSave(byte[] backup, OnFinishRunnable finish) {
super(finish); super(finish);
mBackup = backup; mBackup = backup;

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
@@ -26,13 +26,13 @@ import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwDatabase; import com.kunzisoft.keepass.database.PwDatabase;
import com.kunzisoft.keepass.utils.UriUtil; import com.kunzisoft.keepass.utils.UriUtil;
public class CreateDB extends RunnableOnFinish { public class CreateDBRunnable extends RunnableOnFinish {
private String mFilename; private String mFilename;
private boolean mDontSave; private boolean mDontSave;
private Context ctx; 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); super(finish);
mFilename = filename; mFilename = filename;
@@ -56,7 +56,7 @@ public class CreateDB extends RunnableOnFinish {
App.clearShutdown(); App.clearShutdown();
// Commit changes // Commit changes
SaveDB save = new SaveDB(ctx, db, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, db, mFinish, mDontSave);
mFinish = null; mFinish = null;
save.run(); save.run();
} }

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
@@ -29,18 +29,18 @@ import com.kunzisoft.keepass.database.PwGroup;
* @author bpellin * @author bpellin
* *
*/ */
public class DeleteEntry extends RunnableOnFinish { public class DeleteEntryRunnable extends RunnableOnFinish {
private Database mDb; private Database mDb;
private PwEntry mEntry; private PwEntry mEntry;
private boolean mDontSave; private boolean mDontSave;
private Context ctx; 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); 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); super(finish);
this.mDb = db; this.mDb = db;
@@ -67,17 +67,17 @@ public class DeleteEntry extends RunnableOnFinish {
mFinish = new AfterDelete(mFinish, parent, mEntry, recycle); mFinish = new AfterDelete(mFinish, parent, mEntry, recycle);
// Commit database // Commit database
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterDelete extends OnFinish { private class AfterDelete extends OnFinishRunnable {
private PwGroup mParent; private PwGroup mParent;
private PwEntry mEntry; private PwEntry mEntry;
private boolean recycled; private boolean recycled;
AfterDelete(OnFinish finish, PwGroup parent, PwEntry entry, boolean r) { AfterDelete(OnFinishRunnable finish, PwGroup parent, PwEntry entry, boolean r) {
super(finish); super(finish);
mParent = parent; mParent = parent;

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
@@ -29,19 +29,19 @@ import com.kunzisoft.keepass.database.PwGroup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class DeleteGroup extends RunnableOnFinish { public class DeleteGroupRunnable extends RunnableOnFinish {
private Context mContext; private Context mContext;
private Database mDb; private Database mDb;
private PwGroup<PwGroup, PwGroup, PwEntry> mGroup; private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
private boolean mDontSave; 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); super(finish);
setMembers(ctx, db, group, false); 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); super(finish);
setMembers(ctx, db, group, dontSave); setMembers(ctx, db, group, dontSave);
} }
@@ -67,14 +67,14 @@ public class DeleteGroup extends RunnableOnFinish {
// Remove child entries // Remove child entries
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods
for ( int i = 0; i < childEnt.size(); i++ ) { 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(); task.run();
} }
// Remove child groups // Remove child groups
List<PwGroup> childGrp = new ArrayList<>(mGroup.getChildGroups()); List<PwGroup> childGrp = new ArrayList<>(mGroup.getChildGroups());
for ( int i = 0; i < childGrp.size(); i++ ) { 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(); task.run();
} }
mDb.deleteGroup(mGroup); mDb.deleteGroup(mGroup);
@@ -88,17 +88,17 @@ public class DeleteGroup extends RunnableOnFinish {
mFinish = new AfterDelete(mFinish, parent, mGroup, recycle); mFinish = new AfterDelete(mFinish, parent, mGroup, recycle);
// Commit Database // Commit Database
SaveDB save = new SaveDB(mContext, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterDelete extends OnFinish { private class AfterDelete extends OnFinishRunnable {
private PwGroup mParent; private PwGroup mParent;
private PwGroup mGroup; private PwGroup mGroup;
private boolean recycled; private boolean recycled;
AfterDelete(OnFinish finish, PwGroup parent, PwGroup mGroup, boolean recycle) { AfterDelete(OnFinishRunnable finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
super(finish); super(finish);
this.mParent = parent; this.mParent = parent;

View File

@@ -17,17 +17,17 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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 android.net.Uri;
import java.io.Serializable; import java.io.Serializable;
public class FileOnFinish extends OnFinish implements Serializable { public class FileOnFinishRunnable extends OnFinishRunnable implements Serializable {
private Uri mFilename = null; private Uri mFilename = null;
protected FileOnFinish mOnFinish; protected FileOnFinishRunnable mOnFinish;
public FileOnFinish(FileOnFinish finish) { public FileOnFinishRunnable(FileOnFinishRunnable finish) {
super(finish); super(finish);
mOnFinish = finish; mOnFinish = finish;

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@@ -40,7 +40,7 @@ import com.kunzisoft.keepass.database.exception.KeyFileEmptyException;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
public class LoadDB extends RunnableOnFinish { public class LoadDBRunnable extends RunnableOnFinish {
private Uri mUri; private Uri mUri;
private String mPass; private String mPass;
private Uri mKey; private Uri mKey;
@@ -48,7 +48,7 @@ public class LoadDB extends RunnableOnFinish {
private Context mCtx; private Context mCtx;
private boolean mRememberKeyfile; 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); super(finish);
mDb = db; mDb = db;

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import android.os.Handler; import android.os.Handler;
@@ -29,27 +29,27 @@ import android.widget.Toast;
* @author bpellin * @author bpellin
* *
*/ */
public class OnFinish implements Runnable { public class OnFinishRunnable implements Runnable {
protected boolean mSuccess; protected boolean mSuccess;
protected String mMessage; protected String mMessage;
protected OnFinish mOnFinish; protected OnFinishRunnable mOnFinish;
protected Handler mHandler; protected Handler mHandler;
public OnFinish() { public OnFinishRunnable() {
} }
public OnFinish(Handler handler) { public OnFinishRunnable(Handler handler) {
mOnFinish = null; mOnFinish = null;
mHandler = handler; mHandler = handler;
} }
public OnFinish(OnFinish finish, Handler handler) { public OnFinishRunnable(OnFinishRunnable finish, Handler handler) {
mOnFinish = finish; mOnFinish = finish;
mHandler = handler; mHandler = handler;
} }
public OnFinish(OnFinish finish) { public OnFinishRunnable(OnFinishRunnable finish) {
mOnFinish = finish; mOnFinish = finish;
mHandler = null; mHandler = null;
} }
@@ -75,7 +75,8 @@ public class OnFinish implements Runnable {
} }
} }
} }
// TODO Move
protected void displayMessage(Context ctx) { protected void displayMessage(Context ctx) {
if ( mMessage != null && mMessage.length() > 0 ) { if ( mMessage != null && mMessage.length() > 0 ) {
Toast.makeText(ctx, mMessage, Toast.LENGTH_LONG).show(); 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/>. * 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 abstract class RunnableOnFinish implements Runnable {
public OnFinish mFinish; public OnFinishRunnable mFinish;
public UpdateStatus mStatus; public ProgressTaskUpdater mStatus;
public RunnableOnFinish(OnFinish finish) { public RunnableOnFinish(OnFinishRunnable finish) {
mFinish = 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; mStatus = status;
} }

View File

@@ -17,7 +17,7 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
@@ -26,12 +26,12 @@ import com.kunzisoft.keepass.database.exception.PwDbOutputException;
import java.io.IOException; import java.io.IOException;
public class SaveDB extends RunnableOnFinish { public class SaveDBRunnable extends RunnableOnFinish {
private Database mDb; private Database mDb;
private boolean mDontSave; private boolean mDontSave;
private Context mCtx; 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); super(finish);
mDb = db; mDb = db;
@@ -39,7 +39,7 @@ public class SaveDB extends RunnableOnFinish {
mCtx = ctx; mCtx = ctx;
} }
public SaveDB(Context ctx, Database db, OnFinish finish) { public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish) {
super(finish); super(finish);
mDb = db; mDb = db;

View File

@@ -17,14 +17,14 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwEntry; import com.kunzisoft.keepass.database.PwEntry;
public class UpdateEntry extends RunnableOnFinish { public class UpdateEntryRunnable extends RunnableOnFinish {
private Database mDb; private Database mDb;
private PwEntry mOldE; private PwEntry mOldE;
@@ -32,11 +32,11 @@ public class UpdateEntry extends RunnableOnFinish {
private Context ctx; private Context ctx;
private boolean mDontSave; 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); 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); super(finish);
this.mDb = db; this.mDb = db;
@@ -59,14 +59,14 @@ public class UpdateEntry extends RunnableOnFinish {
mOldE.touch(true, true); mOldE.touch(true, true);
// Commit to disk // Commit to disk
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave); SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
save.run(); save.run();
} }
private class AfterUpdate extends OnFinish { private class AfterUpdate extends OnFinishRunnable {
private PwEntry mBackup; private PwEntry mBackup;
AfterUpdate(PwEntry backup, OnFinish finish) { AfterUpdate(PwEntry backup, OnFinishRunnable finish) {
super(finish); super(finish);
mBackup = backup; mBackup = backup;
} }

View File

@@ -17,14 +17,14 @@
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>. * 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.Context;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.PwGroup; import com.kunzisoft.keepass.database.PwGroup;
public class UpdateGroup extends RunnableOnFinish { public class UpdateGroupRunnable extends RunnableOnFinish {
private Database mDb; private Database mDb;
private PwGroup mOldGroup; private PwGroup mOldGroup;
@@ -32,11 +32,11 @@ public class UpdateGroup extends RunnableOnFinish {
private Context ctx; private Context ctx;
private boolean mDontSave; 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); 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); super(finish);
this.mDb = db; this.mDb = db;
@@ -59,13 +59,13 @@ public class UpdateGroup extends RunnableOnFinish {
mOldGroup.touch(true, true); mOldGroup.touch(true, true);
// Commit to disk // 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; private PwGroup mBackup;
AfterUpdate(PwGroup backup, OnFinish finish) { AfterUpdate(PwGroup backup, OnFinishRunnable finish) {
super(finish); super(finish);
mBackup = backup; 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.PwDatabase;
import com.kunzisoft.keepass.database.exception.InvalidDBException; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -33,8 +33,7 @@ public abstract class Importer {
public abstract PwDatabase openDatabase(InputStream inStream, String password, InputStream keyInputStream) public abstract PwDatabase openDatabase(InputStream inStream, String password, InputStream keyInputStream)
throws IOException, InvalidDBException; 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; 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.LEDataInputStream;
import com.kunzisoft.keepass.stream.LEDataOutputStream; import com.kunzisoft.keepass.stream.LEDataOutputStream;
import com.kunzisoft.keepass.stream.NullOutputStream; 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 com.kunzisoft.keepass.utils.Types;
import java.io.IOException; import java.io.IOException;
@@ -124,15 +124,15 @@ public class ImporterV3 extends Importer {
* @throws InvalidAlgorithmParameterException if error decrypting main file body. * @throws InvalidAlgorithmParameterException if error decrypting main file body.
* @throws ShortBufferException if error decrypting main file body. * @throws ShortBufferException if error decrypting main file body.
*/ */
@Override
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs) public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs)
throws IOException, InvalidDBException throws IOException, InvalidDBException {
{ return openDatabase(inStream, password, kfIs, null, 0);
return openDatabase(inStream, password, kfIs, new UpdateStatus(), 0);
} }
public PwDatabaseV3 openDatabase( InputStream inStream, String password, InputStream kfIs, UpdateStatus status, long roundsFix) @Override
throws IOException, InvalidDBException public PwDatabaseV3 openDatabase(InputStream inStream, String password, InputStream kfIs, ProgressTaskUpdater progressTaskUpdater, long roundsFix)
{ throws IOException, InvalidDBException {
PwDatabaseV3 newManager; PwDatabaseV3 newManager;
@@ -156,7 +156,8 @@ public class ImporterV3 extends Importer {
throw new InvalidDBVersionException(); throw new InvalidDBVersionException();
} }
status.updateMessage(R.string.creating_db_key); if (progressTaskUpdater != null)
progressTaskUpdater.updateMessage(R.string.creating_db_key);
newManager = createDB(); newManager = createDB();
newManager.setMasterKey(password, kfIs); newManager.setMasterKey(password, kfIs);
@@ -177,7 +178,8 @@ public class ImporterV3 extends Importer {
// Generate transformedMasterKey from masterKey // Generate transformedMasterKey from masterKey
newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.getNumberKeyEncryptionRounds()); 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 // Initialize Rijndael algorithm
Cipher cipher; Cipher cipher;
try { try {

View File

@@ -21,7 +21,7 @@ package com.kunzisoft.keepass.database.load;
import com.kunzisoft.keepass.database.PwDatabaseV3Debug; import com.kunzisoft.keepass.database.PwDatabaseV3Debug;
import com.kunzisoft.keepass.database.exception.InvalidDBException; 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.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -35,7 +35,7 @@ public class ImporterV3Debug extends ImporterV3 {
@Override @Override
public PwDatabaseV3Debug openDatabase(InputStream inStream, String password, public PwDatabaseV3Debug openDatabase(InputStream inStream, String password,
InputStream keyInputStream, UpdateStatus status, long roundsFix) throws IOException, InputStream keyInputStream, ProgressTaskUpdater status, long roundsFix) throws IOException,
InvalidDBException { InvalidDBException {
return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyInputStream, status, return (PwDatabaseV3Debug) super.openDatabase(inStream, password, keyInputStream, status,
roundsFix); roundsFix);

View File

@@ -19,6 +19,7 @@
*/ */
package com.kunzisoft.keepass.database.load; package com.kunzisoft.keepass.database.load;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.crypto.CipherFactory; import com.kunzisoft.keepass.crypto.CipherFactory;
import com.kunzisoft.keepass.crypto.PwStreamCipherFactory; import com.kunzisoft.keepass.crypto.PwStreamCipherFactory;
import com.kunzisoft.keepass.crypto.engine.CipherEngine; 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.HashedBlockInputStream;
import com.kunzisoft.keepass.stream.HmacBlockInputStream; import com.kunzisoft.keepass.stream.HmacBlockInputStream;
import com.kunzisoft.keepass.stream.LEDataInputStream; 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.DateUtil;
import com.kunzisoft.keepass.utils.EmptyUtils; import com.kunzisoft.keepass.utils.EmptyUtils;
import com.kunzisoft.keepass.utils.MemUtil; import com.kunzisoft.keepass.utils.MemUtil;
@@ -97,13 +98,16 @@ public class ImporterV4 extends Importer {
public PwDatabaseV4 openDatabase(InputStream inStream, String password, public PwDatabaseV4 openDatabase(InputStream inStream, String password,
InputStream keyInputStream) throws IOException, InvalidDBException { InputStream keyInputStream) throws IOException, InvalidDBException {
return openDatabase(inStream, password, keyInputStream, new UpdateStatus(), 0); return openDatabase(inStream, password, keyInputStream, null, 0);
} }
@Override @Override
public PwDatabaseV4 openDatabase(InputStream inStream, String password, public PwDatabaseV4 openDatabase(InputStream inStream, String password,
InputStream keyInputStream, UpdateStatus status, long roundsFix) throws IOException, InputStream keyInputStream, ProgressTaskUpdater progressTaskUpdater, long roundsFix) throws IOException,
InvalidDBException { InvalidDBException {
if (progressTaskUpdater != null)
progressTaskUpdater.updateMessage(R.string.creating_db_key);
db = createDB(); db = createDB();
PwDbHeaderV4 header = new PwDbHeaderV4(db); PwDbHeaderV4 header = new PwDbHeaderV4(db);
@@ -118,6 +122,8 @@ public class ImporterV4 extends Importer {
db.setMasterKey(password, keyInputStream); db.setMasterKey(password, keyInputStream);
db.makeFinalKey(header.masterSeed, db.getKdfParameters(), roundsFix); db.makeFinalKey(header.masterSeed, db.getKdfParameters(), roundsFix);
if (progressTaskUpdater != null)
progressTaskUpdater.updateMessage(R.string.decrypting_db);
CipherEngine engine; CipherEngine engine;
Cipher cipher; Cipher cipher;
try { try {

View File

@@ -51,8 +51,8 @@ import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.activities.GroupActivity; import com.kunzisoft.keepass.activities.GroupActivity;
import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.autofill.AutofillHelper; import com.kunzisoft.keepass.autofill.AutofillHelper;
import com.kunzisoft.keepass.database.edit.CreateDB; import com.kunzisoft.keepass.database.action.CreateDBRunnable;
import com.kunzisoft.keepass.database.edit.FileOnFinish; import com.kunzisoft.keepass.database.action.FileOnFinishRunnable;
import com.kunzisoft.keepass.database.exception.ContentFileNotFoundException; import com.kunzisoft.keepass.database.exception.ContentFileNotFoundException;
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment; import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
import com.kunzisoft.keepass.dialogs.CreateFileDialogFragment; 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.password.PasswordActivity;
import com.kunzisoft.keepass.settings.PreferencesUtil; import com.kunzisoft.keepass.settings.PreferencesUtil;
import com.kunzisoft.keepass.stylish.StylishActivity; 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.EmptyUtils;
import com.kunzisoft.keepass.utils.MenuUtil; import com.kunzisoft.keepass.utils.MenuUtil;
import com.kunzisoft.keepass.utils.UriUtil; 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 // Prep an object to collect a password once the database has
// been created // been created
FileOnFinish launchActivityOnFinish = new FileOnFinish( FileOnFinishRunnable launchActivityOnFinish = new FileOnFinishRunnable(
new LaunchGroupActivity(databaseFilename)); new LaunchGroupActivity(databaseFilename));
AssignPasswordOnFinish assignPasswordOnFinish = AssignPasswordOnFinish assignPasswordOnFinish =
new AssignPasswordOnFinish(launchActivityOnFinish); new AssignPasswordOnFinish(launchActivityOnFinish);
// Create the new database // Initialize the password helper assigner to set the password after the database creation
CreateDB create = new CreateDB(FileSelectActivity.this,
databaseFilename, assignPasswordOnFinish, true);
ProgressTask createTask = new ProgressTask(
FileSelectActivity.this, create,
R.string.progress_create);
createTask.run();
assignPasswordHelper = new AssignPasswordHelper(this, assignPasswordHelper = new AssignPasswordHelper(this,
masterPasswordChecked, masterPassword, keyFileChecked, keyFile); 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) { } catch (Exception e) {
String error = "Unable to create database with this password and key file"; 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); super(fileOnFinish);
} }
@Override @Override
public void run() { public void run() {
if (mSuccess) { 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; private Uri mUri;
LaunchGroupActivity(String filename) { LaunchGroupActivity(String filename) {

View File

@@ -19,25 +19,30 @@
*/ */
package com.kunzisoft.keepass.password; package com.kunzisoft.keepass.password;
import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; 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.app.App;
import com.kunzisoft.keepass.database.edit.FileOnFinish; import com.kunzisoft.keepass.database.action.AssignPasswordInDBRunnable;
import com.kunzisoft.keepass.database.edit.OnFinish; import com.kunzisoft.keepass.database.action.FileOnFinishRunnable;
import com.kunzisoft.keepass.database.edit.SetPassword; import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.tasks.ProgressTask; 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 { public class AssignPasswordHelper {
private Context context; private AppCompatActivity context;
private String masterPassword = null; private String masterPassword = null;
private Uri keyfile = null; private Uri keyfile = null;
public AssignPasswordHelper(Context context, private boolean createProgressDialog;
public AssignPasswordHelper(AppCompatActivity context,
boolean withMasterPassword, boolean withMasterPassword,
String masterPassword, String masterPassword,
boolean withKeyFile, boolean withKeyFile,
@@ -47,36 +52,66 @@ public class AssignPasswordHelper {
this.masterPassword = masterPassword; this.masterPassword = masterPassword;
if (withKeyFile) if (withKeyFile)
this.keyfile = keyfile; this.keyfile = keyfile;
createProgressDialog = true;
} }
public void assignPasswordInDatabase(FileOnFinish fileOnFinish) { public void setCreateProgressDialog(boolean createProgressDialog) {
SetPassword sp = new SetPassword(context, App.getDB(), masterPassword, keyfile, new AfterSave(fileOnFinish, new Handler())); this.createProgressDialog = createProgressDialog;
final ProgressTask pt = new ProgressTask(context, sp, R.string.saving_database); }
boolean valid = sp.validatePassword(context, (dialog, which) -> pt.run());
if (valid) { public void assignPasswordInDatabase(FileOnFinishRunnable fileOnFinish) {
pt.run(); 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 class AfterSave extends OnFinishRunnable {
private FileOnFinish mFinish; private FileOnFinishRunnable mFinish;
public AfterSave(FileOnFinish finish, Handler handler) { AfterSave(FileOnFinishRunnable finish, Handler handler) {
super(finish, handler); super(finish, handler);
mFinish = finish; mFinish = finish;
} }
@Override @Override
public void run() { public void run() {
if ( mSuccess ) {
if ( mFinish != null ) {
mFinish.setFilename(keyfile);
}
} else {
displayMessage(context);
}
super.run(); 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.ClipDataCompat;
import com.kunzisoft.keepass.compat.EditorCompat; import com.kunzisoft.keepass.compat.EditorCompat;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.edit.LoadDB; import com.kunzisoft.keepass.database.action.LoadDBRunnable;
import com.kunzisoft.keepass.database.edit.OnFinish; import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper; import com.kunzisoft.keepass.dialogs.PasswordEncodingDialogHelper;
import com.kunzisoft.keepass.fileselect.KeyFileHelper; import com.kunzisoft.keepass.fileselect.KeyFileHelper;
import com.kunzisoft.keepass.fingerprint.FingerPrintAnimatedVector; 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.fingerprint.FingerPrintHelper;
import com.kunzisoft.keepass.settings.PreferencesUtil; import com.kunzisoft.keepass.settings.PreferencesUtil;
import com.kunzisoft.keepass.stylish.StylishActivity; 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.EmptyUtils;
import com.kunzisoft.keepass.utils.MenuUtil; import com.kunzisoft.keepass.utils.MenuUtil;
import com.kunzisoft.keepass.utils.UriUtil; import com.kunzisoft.keepass.utils.UriUtil;
@@ -122,6 +123,8 @@ public class PasswordActivity extends StylishActivity
private CompoundButton checkboxKeyfileView; private CompoundButton checkboxKeyfileView;
private CompoundButton checkboxDefaultDatabaseView; private CompoundButton checkboxDefaultDatabaseView;
private ProgressTaskDialogFragment loadingDatabaseDialog;
private DefaultCheckChange defaultCheckChange; private DefaultCheckChange defaultCheckChange;
private ValidateButtonViewClickListener validateButtonViewClickListener; private ValidateButtonViewClickListener validateButtonViewClickListener;
@@ -808,20 +811,86 @@ public class PasswordActivity extends StylishActivity
loadDatabase(password, keyUri); loadDatabase(password, keyUri);
} }
private void loadDatabase(String pass, Uri keyfile) { private void loadDatabase(String password, Uri keyfile) {
// Clear before we load // Clear before we load
Database db = App.getDB(); Database database = App.getDB();
db.clear(); database.clear();
// Clear the shutdown flag // Clear the shutdown flag
App.clearShutdown(); App.clearShutdown();
// Show the progress dialog
Handler handler = new Handler(); 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); * Called after verify and try to opening the database
pt.run(); */
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 @Override
@@ -863,54 +932,6 @@ public class PasswordActivity extends StylishActivity
PasswordActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); 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> { private static class UriIntentInitTask extends AsyncTask<Intent, Void, Integer> {
static final String KEY_FILENAME = "fileName"; static final String KEY_FILENAME = "fileName";

View File

@@ -1,11 +1,12 @@
package com.kunzisoft.keepass.settings.preferenceDialogFragment; package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View; 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 { public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
@@ -37,22 +38,22 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
database.assignDescription(dbDescription); database.assignDescription(dbDescription);
Handler handler = new Handler(); Handler handler = new Handler();
setAfterSaveDatabase(new AfterDescriptionSave(getContext(), handler, dbDescription, oldDescription)); setAfterSaveDatabase(new AfterDescriptionSave((AppCompatActivity) getActivity(), handler, dbDescription, oldDescription));
} }
super.onDialogClosed(positiveResult); super.onDialogClosed(positiveResult);
} }
private class AfterDescriptionSave extends OnFinish { private class AfterDescriptionSave extends OnFinishRunnable {
private AppCompatActivity mActivity;
private String mNewDescription; private String mNewDescription;
private String mOldDescription; 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); super(handler);
mCtx = ctx; mActivity = ctx;
mNewDescription = newDescription; mNewDescription = newDescription;
mOldDescription = oldDescription; mOldDescription = oldDescription;
} }
@@ -62,12 +63,18 @@ public class DatabaseDescriptionPreferenceDialogFragmentCompat extends DatabaseS
String descriptionToShow = mNewDescription; String descriptionToShow = mNewDescription;
if (!mSuccess) { if (!mSuccess) {
displayMessage(mCtx); displayMessage(mActivity);
database.assignDescription(mOldDescription); database.assignDescription(mOldDescription);
database.assignDescription(mOldDescription); database.assignDescription(mOldDescription);
} }
getPreference().setSummary(descriptionToShow); if (mActivity != null) {
mActivity.runOnUiThread(() -> {
getPreference().setSummary(descriptionToShow);
SaveDatabaseProgressTaskDialogFragment.stop(
mActivity.getSupportFragmentManager());
});
}
super.run(); super.run();
} }

View File

@@ -1,11 +1,12 @@
package com.kunzisoft.keepass.settings.preferenceDialogFragment; package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View; 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 { public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
@@ -37,22 +38,22 @@ public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePref
database.assignName(dbName); database.assignName(dbName);
Handler handler = new Handler(); Handler handler = new Handler();
setAfterSaveDatabase(new AfterNameSave(getContext(), handler, dbName, oldName)); setAfterSaveDatabase(new AfterNameSave((AppCompatActivity) getActivity(), handler, dbName, oldName));
} }
super.onDialogClosed(positiveResult); super.onDialogClosed(positiveResult);
} }
private class AfterNameSave extends OnFinish { private class AfterNameSave extends OnFinishRunnable {
private String mNewName; private String mNewName;
private String mOldName; 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); super(handler);
mCtx = ctx; mActivity = ctx;
mNewName = newName; mNewName = newName;
mOldName = oldName; mOldName = oldName;
} }
@@ -62,11 +63,18 @@ public class DatabaseNamePreferenceDialogFragmentCompat extends DatabaseSavePref
String nameToShow = mNewName; String nameToShow = mNewName;
if (!mSuccess) { if (!mSuccess) {
displayMessage(mCtx); displayMessage(mActivity);
database.assignName(mOldName); database.assignName(mOldName);
} }
getPreference().setSummary(nameToShow);
if (mActivity != null) {
mActivity.runOnUiThread(() -> {
getPreference().setSummary(nameToShow);
SaveDatabaseProgressTaskDialogFragment.stop(
mActivity.getSupportFragmentManager());
});
}
super.run(); super.run();
} }

View File

@@ -2,18 +2,18 @@ package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.view.View; import android.view.View;
import com.kunzisoft.keepass.R;
import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.Database;
import com.kunzisoft.keepass.database.edit.OnFinish; import com.kunzisoft.keepass.database.action.OnFinishRunnable;
import com.kunzisoft.keepass.database.edit.SaveDB; import com.kunzisoft.keepass.database.action.SaveDBRunnable;
import com.kunzisoft.keepass.tasks.ProgressTask; import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputPreferenceDialogFragmentCompat { public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputPreferenceDialogFragmentCompat {
protected Database database; protected Database database;
private OnFinish afterSaveDatabase; private OnFinishRunnable afterSaveDatabase;
@Override @Override
protected void onBindDialogView(View view) { protected void onBindDialogView(View view) {
@@ -25,17 +25,21 @@ public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputP
@Override @Override
public void onDialogClosed(boolean positiveResult) { public void onDialogClosed(boolean positiveResult) {
if ( positiveResult ) { if ( positiveResult ) {
assert getContext() != null; assert getActivity() != null;
if (database != null && afterSaveDatabase != null) { if (database != null && afterSaveDatabase != null) {
SaveDB save = new SaveDB(getContext(), database, afterSaveDatabase); SaveDBRunnable saveDBRunnable = new SaveDBRunnable(getContext(), database, afterSaveDatabase);
ProgressTask pt = new ProgressTask(getContext(), save, R.string.saving_database); saveDBRunnable.setUpdateProgressTaskStatus(
pt.run(); new UpdateProgressTaskStatus(getContext(),
SaveDatabaseProgressTaskDialogFragment.start(
getActivity().getSupportFragmentManager())
));
new Thread(saveDBRunnable).start();
} }
} }
} }
public void setAfterSaveDatabase(OnFinish afterSaveDatabase) { public void setAfterSaveDatabase(OnFinishRunnable afterSaveDatabase) {
this.afterSaveDatabase = afterSaveDatabase; this.afterSaveDatabase = afterSaveDatabase;
} }
} }

View File

@@ -19,14 +19,15 @@
*/ */
package com.kunzisoft.keepass.settings.preferenceDialogFragment; package com.kunzisoft.keepass.settings.preferenceDialogFragment;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import com.kunzisoft.keepass.R; 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 { public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreferenceDialogFragmentCompat {
@@ -76,22 +77,22 @@ public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreference
} }
Handler handler = new Handler(); Handler handler = new Handler();
setAfterSaveDatabase(new AfterRoundSave(getContext(), handler, rounds, oldRounds)); setAfterSaveDatabase(new AfterRoundSave((AppCompatActivity) getActivity(), handler, rounds, oldRounds));
} }
super.onDialogClosed(positiveResult); super.onDialogClosed(positiveResult);
} }
private class AfterRoundSave extends OnFinish { private class AfterRoundSave extends OnFinishRunnable {
private long mNewRounds; private long mNewRounds;
private long mOldRounds; 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); super(handler);
mCtx = ctx; mActivity = ctx;
mNewRounds = newRounds; mNewRounds = newRounds;
mOldRounds = oldRounds; mOldRounds = oldRounds;
} }
@@ -101,11 +102,17 @@ public class RoundsPreferenceDialogFragmentCompat extends DatabaseSavePreference
long roundsToShow = mNewRounds; long roundsToShow = mNewRounds;
if (!mSuccess) { if (!mSuccess) {
displayMessage(mCtx); displayMessage(mActivity);
database.setNumberKeyEncryptionRounds(mOldRounds); database.setNumberKeyEncryptionRounds(mOldRounds);
} }
getPreference().setSummary(String.valueOf(roundsToShow)); if (mActivity != null) {
mActivity.runOnUiThread(() -> {
getPreference().setSummary(String.valueOf(roundsToShow));
SaveDatabaseProgressTaskDialogFragment.stop(
mActivity.getSupportFragmentManager());
});
}
super.run(); 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; package com.kunzisoft.keepass.tasks;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
public class UpdateStatus { public class UpdateProgressTaskStatus implements ProgressTaskUpdater {
private ProgressDialog mPD; private Context mContext;
private Context mCtx; private ProgressTaskUpdater mProgressTaskUpdater;
private Handler mHandler; private Handler mHandler;
public UpdateStatus() { public UpdateProgressTaskStatus(Context context, ProgressTaskUpdater progressTaskUpdater) {
this(context, new Handler(), progressTaskUpdater);
} }
public UpdateStatus(Context ctx, Handler handler, ProgressDialog pd) { public UpdateProgressTaskStatus(Context context, Handler handler, ProgressTaskUpdater progressTaskUpdater) {
mCtx = ctx; this.mContext = context;
mPD = pd; this.mProgressTaskUpdater = progressTaskUpdater;
mHandler = handler; this.mHandler = handler;
} }
@Override
public void updateMessage(int resId) { public void updateMessage(int resId) {
if ( mCtx != null && mPD != null && mHandler != null ) { if ( mContext != null && mProgressTaskUpdater != null && mHandler != null ) {
mHandler.post(new UpdateMessage(resId)); mHandler.post(new UpdateMessage(resId));
} }
} }
@@ -47,13 +47,12 @@ public class UpdateStatus {
private class UpdateMessage implements Runnable { private class UpdateMessage implements Runnable {
private int mResId; private int mResId;
public UpdateMessage(int resId) { UpdateMessage(int resId) {
mResId = resId; mResId = resId;
} }
public void run() { public void run() {
mPD.setMessage(mCtx.getString(mResId)); mProgressTaskUpdater.updateMessage(mResId);
} }
} }
} }

View File

@@ -190,6 +190,17 @@
</android.support.design.widget.CoordinatorLayout> </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.support.v7.widget.AppCompatButton
android:id="@+id/pass_ok" android:id="@+id/pass_ok"
android:layout_width="wrap_content" 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