More refactoring and introduction of further abstractions

Added further tests
Fixed test loading with keyfile only
This commit is contained in:
Philipp Crocoll 2013-06-25 21:27:41 +02:00
parent 0435ad54ca
commit 903de8368a
22 changed files with 456 additions and 56 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using Android.Content; using Android.Content;
using Android.OS;
using KeePassLib.Serialization; using KeePassLib.Serialization;
namespace keepass2android namespace keepass2android
@ -49,5 +50,12 @@ namespace keepass2android
EventHandler<DialogClickEventArgs> noHandler, EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler, EventHandler<DialogClickEventArgs> cancelHandler,
Context ctx); Context ctx);
/// <summary>
/// Returns a Handler object which can run tasks on the UI thread
/// </summary>
Handler UiThreadHandler { get; }
IProgressDialog CreateProgressDialog(Context ctx);
} }
} }

View File

@ -0,0 +1,10 @@
namespace keepass2android
{
public interface IProgressDialog
{
void SetTitle(string title);
void SetMessage(string getResourceString);
void Dismiss();
void Show();
}
}

View File

@ -41,6 +41,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="IProgressDialog.cs" />
<Compile Include="PreferenceKey.cs" /> <Compile Include="PreferenceKey.cs" />
<Compile Include="UiStringKey.cs" /> <Compile Include="UiStringKey.cs" />
<Compile Include="database\Database.cs" /> <Compile Include="database\Database.cs" />

View File

@ -28,16 +28,17 @@ namespace keepass2android
public class ProgressTask { public class ProgressTask {
private readonly Handler _handler; private readonly Handler _handler;
private readonly RunnableOnFinish _task; private readonly RunnableOnFinish _task;
private readonly ProgressDialog _progressDialog; private readonly IProgressDialog _progressDialog;
private readonly IKp2aApp _app; private readonly IKp2aApp _app;
private Thread _thread;
public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task, UiStringKey messageKey) { public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task, UiStringKey messageKey) {
_task = task; _task = task;
_handler = new Handler(); _handler = app.UiThreadHandler;
_app = app; _app = app;
// Show process dialog // Show process dialog
_progressDialog = new ProgressDialog(ctx); _progressDialog = app.CreateProgressDialog(ctx);
_progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title)); _progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title));
_progressDialog.SetMessage(_app.GetResourceString(messageKey)); _progressDialog.SetMessage(_app.GetResourceString(messageKey));
@ -53,15 +54,20 @@ namespace keepass2android
// Start Thread to Run task // Start Thread to Run task
Thread t = new Thread(_task.Run); _thread = new Thread(_task.Run);
t.Start(); _thread.Start();
} }
private class AfterTask : OnFinish { public void JoinWorkerThread()
readonly ProgressDialog _progressDialog; {
_thread.Join();
}
public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler) private class AfterTask : OnFinish {
readonly IProgressDialog _progressDialog;
public AfterTask (OnFinish finish, Handler handler, IProgressDialog pd): base(finish, handler)
{ {
_progressDialog = pd; _progressDialog = pd;
} }
@ -69,8 +75,15 @@ namespace keepass2android
public override void Run() { public override void Run() {
base.Run(); base.Run();
if (Handler != null) //can be null in tests
{
// Remove the progress dialog // Remove the progress dialog
Handler.Post(delegate { _progressDialog.Dismiss(); }); Handler.Post(delegate { _progressDialog.Dismiss(); });
}
else
{
_progressDialog.Dismiss();
}
} }

View File

@ -26,7 +26,7 @@ namespace keepass2android
/// StatusLogger implementation which shows the progress in a progress dialog /// StatusLogger implementation which shows the progress in a progress dialog
/// </summary> /// </summary>
public class UpdateStatus: IStatusLogger { public class UpdateStatus: IStatusLogger {
private readonly ProgressDialog _progressDialog; private readonly IProgressDialog _progressDialog;
readonly IKp2aApp _app; readonly IKp2aApp _app;
private readonly Handler _handler; private readonly Handler _handler;
@ -34,7 +34,7 @@ namespace keepass2android
} }
public UpdateStatus(IKp2aApp app, Handler handler, ProgressDialog pd) { public UpdateStatus(IKp2aApp app, Handler handler, IProgressDialog pd) {
_app = app; _app = app;
_progressDialog = pd; _progressDialog = pd;
_handler = handler; _handler = handler;

View File

@ -19,6 +19,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Android.Content; using Android.Content;
using KeePassLib; using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization; using KeePassLib.Serialization;
namespace keepass2android namespace keepass2android
@ -95,21 +96,36 @@ namespace keepass2android
PwDatabase pwDatabase = new PwDatabase(); PwDatabase pwDatabase = new PwDatabase();
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey(); CompositeKey compositeKey = new CompositeKey();
key.AddUserKey(new KeePassLib.Keys.KcpPassword(password)); compositeKey.AddUserKey(new KcpPassword(password));
if (!String.IsNullOrEmpty(keyfile)) if (!String.IsNullOrEmpty(keyfile))
{ {
try try
{ {
key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile)); compositeKey.AddUserKey(new KcpKeyFile(keyfile));
} catch (Exception) } catch (Exception)
{ {
throw new KeyFileException(); throw new KeyFileException();
} }
} }
pwDatabase.Open(iocInfo, key, status); try
{
pwDatabase.Open(iocInfo, compositeKey, status);
}
catch (Exception)
{
if ((password == "") && (keyfile != null))
{
//if we don't get a password, we don't know whether this means "empty password" or "no password"
//retry without password:
compositeKey.RemoveUserKey(compositeKey.GetUserKey(typeof (KcpPassword)));
pwDatabase.Open(iocInfo, compositeKey, status);
}
else throw;
}
if (iocInfo.IsLocalFile()) if (iocInfo.IsLocalFile())
{ {

View File

@ -41,15 +41,17 @@ namespace keepass2android
public override void Run () public override void Run ()
{ {
try { try
{
_app.GetDb().LoadData (_app, _ioc, _pass, _key, Status); _app.GetDb().LoadData (_app, _ioc, _pass, _key, Status);
SaveFileData (_ioc, _key); SaveFileData (_ioc, _key);
} catch (KeyFileException) { } catch (KeyFileException) {
Android.Util.Log.Debug("KP2ATest", "KeyFileException");
Finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ _app.GetResourceString(UiStringKey.keyfile_does_not_exist)); Finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ _app.GetResourceString(UiStringKey.keyfile_does_not_exist));
} }
catch (Exception e) { catch (Exception e) {
Android.Util.Log.Debug("KP2ATest", "Exception: "+e.Message);
Finish(false, "An error occured: " + e.Message); Finish(false, "An error occured: " + e.Message);
return; return;
} }
@ -85,6 +87,7 @@ namespace keepass2android
return; return;
} }
*/ */
Android.Util.Log.Debug("KP2ATest", "LoadDB OK");
Finish(true); Finish(true);
} }

View File

@ -58,7 +58,7 @@ namespace keepass2android
} }
public virtual void Run() { public virtual void Run() {
if ( BaseOnFinish != null ) { if (BaseOnFinish == null) return;
// Pass on result on call finish // Pass on result on call finish
BaseOnFinish.SetResult(Success, Message); BaseOnFinish.SetResult(Success, Message);
@ -68,7 +68,6 @@ namespace keepass2android
BaseOnFinish.Run(); BaseOnFinish.Run();
} }
} }
}
protected void DisplayMessage(Context ctx) { protected void DisplayMessage(Context ctx) {
DisplayMessage(ctx, Message); DisplayMessage(ctx, Message);

View File

@ -46,11 +46,16 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ProgressDialogStub.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestDrawableFactory.cs" /> <Compile Include="TestDrawableFactory.cs" />
<Compile Include="TestCreateDb.cs" /> <Compile Include="TestCreateDb.cs" />
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" /> <Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestKp2aApp.cs" />
<Compile Include="TestLoadDb.cs" />
<Compile Include="TestSaveDb.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Resources\AboutResources.txt" /> <None Include="Resources\AboutResources.txt" />

View File

@ -1,5 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.Runtime; using Android.Runtime;
@ -18,7 +18,9 @@ namespace Kp2aUnitTests
{ {
TestRunner runner = new TestRunner(); TestRunner runner = new TestRunner();
// Run all tests from this assembly // Run all tests from this assembly
runner.AddTests(Assembly.GetExecutingAssembly()); //runner.AddTests(Assembly.GetExecutingAssembly());
runner.AddTests(new List<Type> { typeof(TestLoadDb)});
//runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadWithPasswordOnly"));}}
return runner; return runner;
} }
} }

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
using keepass2android;
namespace Kp2aUnitTests
{
class ProgressDialogStub : IProgressDialog
{
public void SetTitle(string title)
{
}
public void SetMessage(string getResourceString)
{
}
public void Dismiss()
{
Dismissed = true;
}
public void Show()
{
Showed = true;
}
protected bool Showed { get; set; }
public bool Dismissed { get; set; }
}
}

View File

@ -93,14 +93,14 @@ namespace Kp2aUnitTests
public partial class String public partial class String
{ {
// aapt resource value: 0x7f040002
public const int ApplicationName = 2130968578;
// aapt resource value: 0x7f040001 // aapt resource value: 0x7f040001
public const int ApplicationName = 2130968577; public const int Hello = 2130968577;
// aapt resource value: 0x7f040000 // aapt resource value: 0x7f040000
public const int Hello = 2130968576; public const int library_name = 2130968576;
// aapt resource value: 0x7f040002
public const int library_name = 2130968578;
static String() static String()
{ {

View File

@ -0,0 +1,131 @@
using System;
using System.Linq;
using Android.App;
using Android.OS;
using KeePassLib;
using KeePassLib.Interfaces;
using KeePassLib.Keys;
using KeePassLib.Security;
using KeePassLib.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using keepass2android;
namespace Kp2aUnitTests
{
internal class TestBase
{
private PwGroup mailGroup;
private PwEntry mailEntry;
/// <summary>
/// Compares the two databases. uses Asserts
/// TODO: implement this with many more checks or use serialization?
/// </summary>
protected void AssertDatabasesAreEqual(PwDatabase db1, PwDatabase db2)
{
db1.RootGroup.GetObjects(true, null)
.ForEach(
item =>
{
IStructureItem foundItem = db2.RootGroup.FindObject(item.Uuid, true, null);
Assert.IsNotNull(foundItem);
Assert.IsTrue(item.ParentGroup.Uuid.EqualsValue(foundItem.ParentGroup.Uuid));
}
);
Assert.AreEqual(db1.RootGroup.GetObjects(true,null).Count(),db2.RootGroup.GetObjects(true,null).Count());
}
protected static string DefaultDirectory
{
get { return "/mnt/sdcard/kp2atest/"; }
}
protected static string DefaultFilename
{
get { return "/mnt/sdcard/kp2atest/savetest.kdbx"; }
}
protected string DefaultKeyfile
{
get { return DefaultDirectory + "keyfile.txt"; }
}
protected string DefaultPassword
{
get { return "secretpassword!"; }
}
protected IKp2aApp LoadDatabase(string defaultFilename, string password, string keyfile)
{
IKp2aApp app = new TestKp2aApp();
Handler handler = new Handler(Looper.MainLooper);
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, new IOConnectionInfo() { Path = defaultFilename }, password, keyfile, new ActionOnFinish((success, message) =>
{
loadSuccesful = success; if (!success)
Assert.Fail(message);
})
);
ProgressTask pt = new ProgressTask(app, Application.Context, task, UiStringKey.loading_database);
pt.Run();
Assert.IsTrue(loadSuccesful);
return app;
}
protected void SaveDatabase(IKp2aApp app)
{
bool saveSuccesful = false;
SaveDb save = new SaveDb(Application.Context, app.GetDb(), new ActionOnFinish((success, message) =>
{
saveSuccesful = success; if (!success)
Assert.Fail(message);
}), false);
save.Run();
Assert.IsTrue(saveSuccesful);
}
protected IKp2aApp SetupAppWithDefaultDatabase()
{
IKp2aApp app = new TestKp2aApp();
IOConnectionInfo ioc = new IOConnectionInfo {Path = DefaultFilename};
Database db = app.CreateNewDatabase();
db.KpDatabase = new PwDatabase();
//Key will be changed/created immediately after creation:
CompositeKey tempKey = new CompositeKey();
db.KpDatabase.New(ioc, tempKey);
db.KpDatabase.KeyEncryptionRounds = 3;
db.KpDatabase.Name = "Keepass2Android Testing Password Database";
// Set Database state
db.Root = db.KpDatabase.RootGroup;
db.Ioc = ioc;
db.Loaded = true;
db.SearchHelper = new SearchDbHelper(app);
// Add a couple default groups
db.KpDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Internet", PwIcon.Key), true);
mailGroup = new PwGroup(true, true, "eMail", PwIcon.UserCommunication);
db.KpDatabase.RootGroup.AddGroup(mailGroup, true);
mailGroup.AddGroup(new PwGroup(true, true, "business", PwIcon.BlackBerry), true );
mailEntry = new PwEntry(true, true);
mailEntry.Strings.Set(PwDefs.UserNameField, new ProtectedString(
true, "me@there.com"));
mailEntry.Strings.Set(PwDefs.TitleField, new ProtectedString(
true, "me@there.com Entry"));
mailGroup.AddEntry(mailEntry , true);
db.KpDatabase.RootGroup.AddGroup(new PwGroup(true, true, "eMail2", PwIcon.UserCommunication), true);
return app;
}
}
}

View File

@ -1,9 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Android.App; using Android.App;
using Java.IO; using Java.IO;
using KeePassLib; using KeePassLib;
using KeePassLib.Interfaces;
using KeePassLib.Keys; using KeePassLib.Keys;
using KeePassLib.Serialization; using KeePassLib.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
@ -12,15 +13,15 @@ using keepass2android;
namespace Kp2aUnitTests namespace Kp2aUnitTests
{ {
[TestClass] [TestClass]
class TestCreateDb class TestCreateDb: TestBase
{ {
[TestMethod] [TestMethod]
public void CreateAndSaveLocal() public void CreateAndSaveLocal()
{ {
IKp2aApp app = new TestKp2aApp(); IKp2aApp app = new TestKp2aApp();
IOConnectionInfo ioc = new IOConnectionInfo {Path = "/mnt/sdcard/kp2atest/savetest.kdbx"}; IOConnectionInfo ioc = new IOConnectionInfo {Path = DefaultFilename};
File outputDir = new File("/mnt/sdcard/kp2atest/"); File outputDir = new File(DefaultDirectory);
outputDir.Mkdirs(); outputDir.Mkdirs();
File targetFile = new File(ioc.Path); File targetFile = new File(ioc.Path);
if (targetFile.Exists()) if (targetFile.Exists())
@ -45,6 +46,10 @@ namespace Kp2aUnitTests
PwDatabase loadedDb = new PwDatabase(); PwDatabase loadedDb = new PwDatabase();
loadedDb.Open(ioc, new CompositeKey(), null); loadedDb.Open(ioc, new CompositeKey(), null);
//Check whether the databases are equal
AssertDatabasesAreEqual(loadedDb, app.GetDb().KpDatabase);
} }
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using Android.Content; using Android.Content;
using Android.OS;
using KeePassLib.Serialization; using KeePassLib.Serialization;
using keepass2android; using keepass2android;
@ -50,5 +51,13 @@ namespace Kp2aUnitTests
{ {
yesHandler(null, null); yesHandler(null, null);
} }
public Handler UiThreadHandler {
get { return null; } //ensure everything runs in the same thread. Otherwise the OnFinish-callback would run after the test has already finished (with failure)
}
public IProgressDialog CreateProgressDialog(Context ctx)
{
return new ProgressDialogStub();
}
} }
} }

View File

@ -0,0 +1,78 @@
using System.Linq;
using System.Threading;
using Android.App;
using Android.OS;
using KeePassLib.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using keepass2android;
namespace Kp2aUnitTests
{
[TestClass]
internal class TestLoadDb : TestBase
{
private string TestDbDirectory
{
get { return DefaultDirectory + "savedWithDesktop/"; }
}
private void RunLoadTest(string filenameWithoutDir, string password, string keyfile)
{
Android.Util.Log.Debug("KP2ATest", "Starting for " + filenameWithoutDir+" with " + password+"/"+keyfile);
IKp2aApp app = new TestKp2aApp();
app.CreateNewDatabase();
bool loadSuccesful = false;
LoadDb task = new LoadDb(app, new IOConnectionInfo() { Path = TestDbDirectory+filenameWithoutDir },
password, keyfile, new ActionOnFinish((success, message) =>
{
if (!success)
Android.Util.Log.Debug("KP2ATest", "error loading db: " + message);
loadSuccesful = success;
})
);
ProgressTask pt = new ProgressTask(app, Application.Context, task, UiStringKey.loading_database);
Android.Util.Log.Debug("KP2ATest", "Running ProgressTask");
pt.Run();
pt.JoinWorkerThread();
Android.Util.Log.Debug("KP2ATest", "PT.run finished");
Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-(");
Assert.AreEqual(6,app.GetDb().KpDatabase.RootGroup.Groups.Count());
Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count());
}
[TestMethod]
public void TestLoadWithPasswordOnly()
{
RunLoadTest("passwordonly.kdbx", DefaultPassword, "");
}
[TestMethod]
public void TestLoadWithKeyfileOnly()
{
RunLoadTest("keyfileonly.kdbx", "", TestDbDirectory + "keyfile.txt");
}
[TestMethod]
public void TestLoadWithPasswordAndKeyfile()
{
RunLoadTest("PasswordAndKeyfile.kdbx", DefaultPassword, TestDbDirectory + "keyfile.txt");
}
[TestMethod]
public void TestLoadWithEmptyPassword()
{
RunLoadTest("EmptyPasswordAndKeyfile.kdbx", "", TestDbDirectory + "keyfile.txt");
}
[TestMethod]
public void TestLoadWithEmptyPasswordOnly()
{
RunLoadTest("EmptyPassword.kdbx", "", "");
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using Android.App;
using Android.OS;
using KeePassLib;
using KeePassLib.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using keepass2android;
namespace Kp2aUnitTests
{
[TestClass]
class TestSaveDb: TestBase
{
[TestMethod]
public void TestLoadEditSave()
{
//create the default database:
IKp2aApp app = SetupAppWithDefaultDatabase();
//save it and reload it so we have a base version
SaveDatabase(app);
app = LoadDatabase(DefaultFilename, DefaultPassword, DefaultKeyfile);
//modify the database by adding a group:
app.GetDb().KpDatabase.RootGroup.AddGroup(new PwGroup(true, true, "TestGroup", PwIcon.Apple), true);
//save the database again:
// -> Ensure Assert below works! SaveDatabase(app, DefaultFilename);
//load database to a new app instance:
IKp2aApp resultApp = LoadDatabase(DefaultFilename, DefaultPassword, DefaultKeyfile);
//ensure the change was saved:
AssertDatabasesAreEqual(app.GetDb().KpDatabase, resultApp.GetDb().KpDatabase);
}
[TestMethod]
public void TestLoadAndSave_TestIdenticalFiles()
{
Assert.Fail("Todo: implement");
}
}
}

View File

@ -399,24 +399,24 @@ namespace keepass2android
EntryEditActivity act = this; EntryEditActivity act = this;
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectTitle, entry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectTitle,
Util.getEditText(act, Resource.Id.entry_title))); Util.GetEditText(act, Resource.Id.entry_title)));
entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUserName, entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUserName,
Util.getEditText(act, Resource.Id.entry_user_name))); Util.GetEditText(act, Resource.Id.entry_user_name)));
String pass = Util.getEditText(act, Resource.Id.entry_password); String pass = Util.GetEditText(act, Resource.Id.entry_password);
byte[] password = StrUtil.Utf8.GetBytes(pass); byte[] password = StrUtil.Utf8.GetBytes(pass);
entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectPassword, entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectPassword,
password)); password));
MemUtil.ZeroByteArray(password); MemUtil.ZeroByteArray(password);
entry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUrl, entry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUrl,
Util.getEditText(act, Resource.Id.entry_url))); Util.GetEditText(act, Resource.Id.entry_url)));
entry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectNotes, entry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectNotes,
Util.getEditText(act, Resource.Id.entry_comment))); Util.GetEditText(act, Resource.Id.entry_comment)));
// Validate expiry date // Validate expiry date
DateTime newExpiry = new DateTime(); DateTime newExpiry = new DateTime();
if ((State.Entry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry))) if ((State.Entry.Expires) && (!DateTime.TryParse( Util.GetEditText(this,Resource.Id.entry_expires), out newExpiry)))
{ {
//ignore here //ignore here
} }
@ -454,9 +454,9 @@ namespace keepass2android
} }
entry.OverrideUrl = Util.getEditText(this,Resource.Id.entry_override_url); entry.OverrideUrl = Util.GetEditText(this,Resource.Id.entry_override_url);
List<string> vNewTags = StrUtil.StringToTags(Util.getEditText(this,Resource.Id.entry_tags)); List<string> vNewTags = StrUtil.StringToTags(Util.GetEditText(this,Resource.Id.entry_tags));
entry.Tags.Clear(); entry.Tags.Clear();
foreach(string strTag in vNewTags) entry.AddTag(strTag); foreach(string strTag in vNewTags) entry.AddTag(strTag);
@ -850,15 +850,15 @@ namespace keepass2android
protected bool ValidateBeforeSaving() { protected bool ValidateBeforeSaving() {
// Require title // Require title
String title = Util.getEditText(this, Resource.Id.entry_title); String title = Util.GetEditText(this, Resource.Id.entry_title);
if ( title.Length == 0 ) { if ( title.Length == 0 ) {
Toast.MakeText(this, Resource.String.error_title_required, ToastLength.Long).Show(); Toast.MakeText(this, Resource.String.error_title_required, ToastLength.Long).Show();
return false; return false;
} }
// Validate password // Validate password
String pass = Util.getEditText(this, Resource.Id.entry_password); String pass = Util.GetEditText(this, Resource.Id.entry_password);
String conf = Util.getEditText(this, Resource.Id.entry_confpassword); String conf = Util.GetEditText(this, Resource.Id.entry_confpassword);
if ( ! pass.Equals(conf) ) { if ( ! pass.Equals(conf) ) {
Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show(); Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show();
return false; return false;
@ -866,7 +866,7 @@ namespace keepass2android
// Validate expiry date // Validate expiry date
DateTime newExpiry = new DateTime(); DateTime newExpiry = new DateTime();
if ((State.Entry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry))) if ((State.Entry.Expires) && (!DateTime.TryParse( Util.GetEditText(this,Resource.Id.entry_expires), out newExpiry)))
{ {
Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show(); Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show();
return false; return false;

View File

@ -517,7 +517,7 @@ namespace keepass2android
} }
private String GetEditText(int resId) { private String GetEditText(int resId) {
return Util.getEditText(this, resId); return Util.GetEditText(this, resId);
} }
private void SetEditText(int resId, String str) { private void SetEditText(int resId, String str) {

View File

@ -82,18 +82,18 @@ namespace keepass2android
gotoUrl(context, donateUrl); gotoUrl(context, donateUrl);
} }
public static String getEditText(Activity act, int resId) { public static String GetEditText(Activity act, int resId) {
TextView te = (TextView) act.FindViewById(resId); TextView te = (TextView) act.FindViewById(resId);
System.Diagnostics.Debug.Assert(te != null); System.Diagnostics.Debug.Assert(te != null);
if (te != null) { if (te != null) {
return te.Text.ToString(); return te.Text;
} else { } else {
return ""; return "";
} }
} }
public static void setEditText(Activity act, int resId, String str) { public static void SetEditText(Activity act, int resId, String str) {
TextView te = (TextView) act.FindViewById(resId); TextView te = (TextView) act.FindViewById(resId);
System.Diagnostics.Debug.Assert(te != null); System.Diagnostics.Debug.Assert(te != null);

View File

@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System; using System;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.OS;
using Android.Runtime; using Android.Runtime;
using KeePassLib.Serialization; using KeePassLib.Serialization;
using Android.Preferences; using Android.Preferences;
@ -177,6 +178,48 @@ namespace keepass2android
} }
public Handler UiThreadHandler
{
get { return new Handler(); }
}
/// <summary>
/// Simple wrapper around ProgressDialog implementing IProgressDialog
/// </summary>
private class RealProgressDialog : IProgressDialog
{
private readonly ProgressDialog _pd;
public RealProgressDialog(Context ctx)
{
this._pd = new ProgressDialog(ctx);
}
public void SetTitle(string title)
{
_pd.SetTitle(title);
}
public void SetMessage(string message)
{
_pd.SetMessage(message);
}
public void Dismiss()
{
_pd.Dismiss();
}
public void Show()
{
_pd.Show();
}
}
public IProgressDialog CreateProgressDialog(Context ctx)
{
return new RealProgressDialog(ctx);
}
internal void OnTerminate() internal void OnTerminate()

View File

@ -81,6 +81,7 @@ namespace MonoDroidUnitTesting {
ISharedPreferencesEditor e = GetPreferences().Edit(); ISharedPreferencesEditor e = GetPreferences().Edit();
e.PutString(ACTIVITY_PREFS_NAME, typeof(TestClassResultActivity).Name); e.PutString(ACTIVITY_PREFS_NAME, typeof(TestClassResultActivity).Name);
if (m_testClass != null)
e.PutString(INTENT_PARAM_NAME, this.m_testClass.Class.AssemblyQualifiedName); e.PutString(INTENT_PARAM_NAME, this.m_testClass.Class.AssemblyQualifiedName);
e.Commit(); e.Commit();
} }