diff --git a/src/KeePassLib2Android/IDatabaseLoader.cs b/src/KeePassLib2Android/IDatabaseLoader.cs new file mode 100644 index 00000000..dd9be389 --- /dev/null +++ b/src/KeePassLib2Android/IDatabaseLoader.cs @@ -0,0 +1,13 @@ +using System.IO; +using KeePassLib.Interfaces; +using KeePassLib.Keys; + +namespace KeePassLib +{ + public interface IDatabaseLoader + { + void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger); + + byte[] HashOfLastStream { get; } + } +} \ No newline at end of file diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj index 2097a03d..8c15bdfc 100644 --- a/src/KeePassLib2Android/KeePassLib2Android.csproj +++ b/src/KeePassLib2Android/KeePassLib2Android.csproj @@ -20,7 +20,7 @@ full False bin\Debug - DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE + DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE prompt 4 False @@ -58,6 +58,7 @@ + @@ -153,11 +154,11 @@ - - - {A57B3ACE-5634-469A-88C4-858BB409F356} - kp2akeytransform + + {70d3844a-d9fa-4a64-b205-a84c6a822196} + KP2AKdbLibraryBinding + \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/IKp2aApp.cs b/src/Kp2aBusinessLogic/IKp2aApp.cs index c0d41952..e8c63a19 100644 --- a/src/Kp2aBusinessLogic/IKp2aApp.cs +++ b/src/Kp2aBusinessLogic/IKp2aApp.cs @@ -3,6 +3,7 @@ using Android.App; using System.IO; using Android.Content; using Android.OS; +using KeePassLib; using KeePassLib.Keys; using KeePassLib.Serialization; using keepass2android.Io; @@ -23,7 +24,7 @@ namespace keepass2android /// /// Loads the specified data as the currently open database, as unlocked. /// - void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger); + void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader); /// /// Returns the current database diff --git a/src/Kp2aBusinessLogic/database/Database.cs b/src/Kp2aBusinessLogic/database/Database.cs index 8bc24383..2b9a94b7 100644 --- a/src/Kp2aBusinessLogic/database/Database.cs +++ b/src/Kp2aBusinessLogic/database/Database.cs @@ -93,34 +93,15 @@ namespace keepass2android /// /// Do not call this method directly. Call App.Kp2a.LoadDatabase instead. /// - public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, CompositeKey compositeKey, ProgressDialogStatusLogger status) + public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, MemoryStream databaseData, CompositeKey compositeKey, ProgressDialogStatusLogger status, IDatabaseLoader databaseLoader) { PwDatabase pwDatabase = new PwDatabase(); IFileStorage fileStorage = _app.GetFileStorage(iocInfo); - var filename = fileStorage.GetFilenameWithoutPathAndExt(iocInfo); - try - { - var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); - pwDatabase.Open(databaseData ?? fileStorage.OpenFileForRead(iocInfo), filename, iocInfo, compositeKey, status); - LastFileVersion = fileVersion; - } - catch (InvalidCompositeKeyException) - { - KcpPassword passwordKey = (KcpPassword)compositeKey.GetUserKey(typeof(KcpPassword)); - - if ((passwordKey != null) && (passwordKey.Password.ReadString() == "") && (compositeKey.UserKeyCount > 1)) - { - //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))); - var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); - //don't reuse the memory stream databaseData: it's already closed. - //We could try to avoid reading the file again here, but probably the case is rare enough so this is ok. - pwDatabase.Open(fileStorage.OpenFileForRead(iocInfo), filename, iocInfo, compositeKey, status); - LastFileVersion = fileVersion; } - else throw; - } + Stream s = databaseData ?? fileStorage.OpenFileForRead(iocInfo); + var fileVersion = _app.GetFileStorage(iocInfo).GetCurrentFileVersionFast(iocInfo); + PopulateDatabaseFromStream(pwDatabase, s, iocInfo, compositeKey, status, databaseLoader); + LastFileVersion = fileVersion; status.UpdateSubMessage(""); @@ -133,7 +114,14 @@ namespace keepass2android SearchHelper = new SearchDbHelper(app); } - + protected virtual void PopulateDatabaseFromStream(PwDatabase pwDatabase, Stream s, IOConnectionInfo iocInfo, CompositeKey compositeKey, ProgressDialogStatusLogger status, IDatabaseLoader databaseLoader) + { + IFileStorage fileStorage = _app.GetFileStorage(iocInfo); + var filename = fileStorage.GetFilenameWithoutPathAndExt(iocInfo); + pwDatabase.Open(s, filename, iocInfo, compositeKey, status, databaseLoader); + } + + public PwGroup SearchForText(String str) { PwGroup group = SearchHelper.SearchForText(this, str); @@ -162,7 +150,7 @@ namespace keepass2android } - public void SaveData(Context ctx) { + public virtual void SaveData(Context ctx) { KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions); using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions)) diff --git a/src/Kp2aBusinessLogic/database/KdbDatabaseLoader.cs b/src/Kp2aBusinessLogic/database/KdbDatabaseLoader.cs new file mode 100644 index 00000000..d282a685 --- /dev/null +++ b/src/Kp2aBusinessLogic/database/KdbDatabaseLoader.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using Android.Content; +using Com.Keepassdroid.Database; +using Com.Keepassdroid.Database.Exception; +using Java.Lang; +using KeePassLib; +using KeePassLib.Cryptography; +using KeePassLib.Cryptography.Cipher; +using KeePassLib.Interfaces; +using KeePassLib.Keys; +using Exception = System.Exception; + +namespace keepass2android +{ + class KdbDatabaseLoader: IDatabaseLoader + { + private Context _ctx; + + public KdbDatabaseLoader(Context ctx) + { + _ctx = ctx; + } + + public void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger) + { + var importer = new Com.Keepassdroid.Database.Load.ImporterV3(); + + var hashingStream = new HashingStreamEx(s, false, new SHA256Managed()); + + string password = "";//no need to distinguish between null and "" because empty passwords are invalid (and null is not allowed) + KcpPassword passwordKey = (KcpPassword)key.GetUserKey(typeof(KcpPassword)); + if (passwordKey != null) + { + password = passwordKey.Password.ReadString(); + } + + KcpKeyFile passwordKeyfile = (KcpKeyFile)key.GetUserKey(typeof(KcpKeyFile)); + string keyfile = ""; + if (passwordKeyfile != null) + { + keyfile = passwordKeyfile.Path; + } + + + try + { + var dbv3 = importer.OpenDatabase(hashingStream, password, keyfile); + + db.Name = dbv3.Name; + } + catch (InvalidPasswordException e) { + + return; + } + catch (Java.IO.FileNotFoundException e) + { + throw new FileNotFoundException( + e.Message, e); + } + catch (Java.Lang.Exception e) + { + throw new Exception(e.LocalizedMessage ?? + e.Message ?? + e.GetType().Name, e); + } + + HashOfLastStream = hashingStream.Hash; + if (HashOfLastStream == null) + throw new Exception("hashing didn't work"); //todo remove + } + + public byte[] HashOfLastStream { get; private set; } + } +} \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/database/KdbxDatabaseLoader.cs b/src/Kp2aBusinessLogic/database/KdbxDatabaseLoader.cs new file mode 100644 index 00000000..828471e4 --- /dev/null +++ b/src/Kp2aBusinessLogic/database/KdbxDatabaseLoader.cs @@ -0,0 +1,31 @@ +using System.IO; +using KeePassLib; +using KeePassLib.Interfaces; +using KeePassLib.Keys; +using KeePassLib.Serialization; + +namespace keepass2android +{ + public class KdbxDatabaseLoader : IDatabaseLoader + { + private readonly KdbxFormat _format; + + public KdbxDatabaseLoader(KdbxFormat format) + { + _format = format; + } + + public void PopulateDatabaseFromStream(PwDatabase db, CompositeKey key, Stream s, IStatusLogger slLogger) + { + KdbxFile kdbx = new KdbxFile(db); + kdbx.DetachBinaries = db.DetachBinaries; + + kdbx.Load(s, _format, slLogger); + HashOfLastStream = kdbx.HashOfFileOnDisk; + s.Close(); + + } + + public byte[] HashOfLastStream { get; private set; } + } +} \ No newline at end of file diff --git a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs index 58f69ab2..2bc6f195 100644 --- a/src/Kp2aBusinessLogic/database/edit/LoadDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/LoadDB.cs @@ -19,6 +19,8 @@ using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using Android.App; +using KeePassLib; using KeePassLib.Keys; using KeePassLib.Serialization; @@ -50,10 +52,24 @@ namespace keepass2android try { StatusLogger.UpdateMessage(UiStringKey.loading_database); - MemoryStream memoryStream = _databaseData == null ? null : _databaseData.Result; - _app.LoadDatabase(_ioc, memoryStream, _compositeKey, StatusLogger); - SaveFileData(_ioc, _keyfileOrProvider); + //get the stream data into a single stream variable (databaseStream) regardless whether its preloaded or not: + MemoryStream preloadedMemoryStream = _databaseData == null ? null : _databaseData.Result; + MemoryStream databaseStream; + if (preloadedMemoryStream != null) + databaseStream = preloadedMemoryStream; + else + { + using (Stream s = _app.GetFileStorage(_ioc).OpenFileForRead(_ioc)) + { + databaseStream = new MemoryStream(); + s.CopyTo(databaseStream); + databaseStream.Seek(0, SeekOrigin.Begin); + } + } + //ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess: + IDatabaseLoader loader = new KdbxDatabaseLoader(KdbpFile.GetFormatToUse(_ioc)); + TryLoad(databaseStream, loader); } catch (KeyFileException) { @@ -73,11 +89,6 @@ namespace keepass2android Finish(false, _app.GetResourceString(UiStringKey.ErrorOcurred) + " " + message); return; } - catch (OldFormatException ) - { - Finish(false, "Cannot open Keepass 1.x database. As explained in the app description, Keepass2Android is for Keepass 2 only! Please use the desktop application to convert your database to the new file format!"); - return; - } catch (Exception e) { Kp2aLog.Log("Exception: " + e); @@ -85,10 +96,48 @@ namespace keepass2android return; } - Kp2aLog.Log("LoadDB OK"); - Finish(true); + } - + + private void TryLoad(MemoryStream databaseStream, IDatabaseLoader loader) + { + //create a copy of the stream so we can try again if we get an exception which indicates we should change parameters + //This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors. + //Alternatives would involve increased traffic (if file is on remote) and slower loading times, so this seems to be the best choice. + MemoryStream workingCopy = new MemoryStream(); + databaseStream.CopyTo(workingCopy); + workingCopy.Seek(0, SeekOrigin.Begin); + //reset stream if we need to reuse it later: + databaseStream.Seek(0, SeekOrigin.Begin); + //now let's go: + try + { + _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, loader); + SaveFileData(_ioc, _keyfileOrProvider); + Kp2aLog.Log("LoadDB OK"); + Finish(true); + } + catch (OldFormatException) + { + TryLoad(databaseStream, new KdbDatabaseLoader(Application.Context)); + } + catch (InvalidCompositeKeyException) + { + KcpPassword passwordKey = (KcpPassword)_compositeKey.GetUserKey(typeof(KcpPassword)); + + if ((passwordKey != null) && (passwordKey.Password.ReadString() == "") && (_compositeKey.UserKeyCount > 1)) + { + //if we don't get a password, we don't know whether this means "empty password" or "no password" + //retry without password: + _compositeKey.RemoveUserKey(passwordKey); + //retry: + TryLoad(databaseStream, loader); + } + else throw; + } + + } + private void SaveFileData(IOConnectionInfo ioc, String keyfileOrProvider) { if (!_rememberKeyfile) diff --git a/src/Kp2aUnitTests/Kp2aUnitTests.csproj b/src/Kp2aUnitTests/Kp2aUnitTests.csproj index ed4c444c..df73b6a0 100644 --- a/src/Kp2aUnitTests/Kp2aUnitTests.csproj +++ b/src/Kp2aUnitTests/Kp2aUnitTests.csproj @@ -16,6 +16,13 @@ Resources\Resource.Designer.cs Off Properties\AndroidManifest.xml + + v4.2 + armeabi,armeabi-v7a,x86 + + + + true @@ -96,8 +103,12 @@ {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA} Kp2aBusinessLogic + + {70d3844a-d9fa-4a64-b205-a84c6a822196} + KP2AKdbLibraryBinding + - {a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48} + {A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48} MonoDroidUnitTesting diff --git a/src/Kp2aUnitTests/MainActivity.cs b/src/Kp2aUnitTests/MainActivity.cs index 0301706d..b96535eb 100644 --- a/src/Kp2aUnitTests/MainActivity.cs +++ b/src/Kp2aUnitTests/MainActivity.cs @@ -20,13 +20,14 @@ namespace Kp2aUnitTests // Run all tests from this assembly //runner.AddTests(Assembly.GetExecutingAssembly()); //runner.AddTests(new List { typeof(TestSynchronizeCachedDatabase)}); - runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure")); - - //runner.AddTests(new List { typeof(TestSaveDb) }); + //runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure")); + + //runner.AddTests(new List { typeof(TestLoadDb) }); //runner.AddTests(new List { typeof(TestCachingFileStorage) }); - //runner.AddTests(typeof(TestCachingFileStorage).GetMethod("TestSaveToRemote")); - //runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly")); - //runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadKdbxAndSaveKdbp_TestIdenticalFiles")); + runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdb1")); + runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadWithKeyfileOnly")); + runner.AddTests(typeof(TestLoadDb).GetMethod("TestLoadKdbpWithPasswordOnly")); + runner.AddTests(typeof(TestSaveDb).GetMethod("TestLoadKdbxAndSaveKdbp_TestIdenticalFiles")); return runner; } } diff --git a/src/Kp2aUnitTests/TestCreateDb.cs b/src/Kp2aUnitTests/TestCreateDb.cs index f109ee7b..2b11f005 100644 --- a/src/Kp2aUnitTests/TestCreateDb.cs +++ b/src/Kp2aUnitTests/TestCreateDb.cs @@ -43,7 +43,7 @@ namespace Kp2aUnitTests //ensure the the database can be loaded from file: PwDatabase loadedDb = new PwDatabase(); - loadedDb.Open(ioc, new CompositeKey(), null); + loadedDb.Open(ioc, new CompositeKey(), null, new KdbxDatabaseLoader(KdbxFormat.Default)); //Check whether the databases are equal AssertDatabasesAreEqual(loadedDb, app.GetDb().KpDatabase); diff --git a/src/Kp2aUnitTests/TestKp2aApp.cs b/src/Kp2aUnitTests/TestKp2aApp.cs index 89e811c0..2695fee7 100644 --- a/src/Kp2aUnitTests/TestKp2aApp.cs +++ b/src/Kp2aUnitTests/TestKp2aApp.cs @@ -5,6 +5,7 @@ using System.Net.Security; using Android.App; using Android.Content; using Android.OS; +using KeePassLib; using KeePassLib.Keys; using KeePassLib.Serialization; using keepass2android; @@ -48,10 +49,9 @@ namespace Kp2aUnitTests throw new NotImplementedException(); } - public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, - ProgressDialogStatusLogger statusLogger) + public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader) { - _db.LoadData(this, ioConnectionInfo, memoryStream, compKey, statusLogger); + _db.LoadData(this, ioConnectionInfo, memoryStream, compKey, statusLogger, databaseLoader); } public Database GetDb() { diff --git a/src/Kp2aUnitTests/TestLoadDb.cs b/src/Kp2aUnitTests/TestLoadDb.cs index 9d515d47..46ee49c6 100644 --- a/src/Kp2aUnitTests/TestLoadDb.cs +++ b/src/Kp2aUnitTests/TestLoadDb.cs @@ -20,10 +20,12 @@ namespace Kp2aUnitTests app.CreateNewDatabase(); bool loadSuccesful = false; var key = CreateKey(password, keyfile); + string loadErrorMessage = ""; LoadDb task = new LoadDb(app, new IOConnectionInfo { Path = TestDbDirectory+filenameWithoutDir }, null, key, keyfile, new ActionOnFinish((success, message) => { + loadErrorMessage = message; if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; @@ -34,7 +36,7 @@ namespace Kp2aUnitTests pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); - Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-("); + Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-( "+loadErrorMessage); Assert.AreEqual(6,app.GetDb().KpDatabase.RootGroup.Groups.Count()); Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count()); @@ -48,6 +50,14 @@ namespace Kp2aUnitTests { RunLoadTest("passwordonly.kdbx", DefaultPassword, ""); } + + + [TestMethod] + public void TestLoadKdb1() + { + RunLoadTest("test1.kdb", "12345", ""); + } + [TestMethod] public void TestLoadWithKeyfileOnly() { diff --git a/src/java/kp2akeytransform/.classpath b/src/java/kp2akeytransform/.classpath index d57ec025..51769745 100644 --- a/src/java/kp2akeytransform/.classpath +++ b/src/java/kp2akeytransform/.classpath @@ -2,8 +2,8 @@ + - diff --git a/src/java/kp2akeytransform/AndroidManifest.xml b/src/java/kp2akeytransform/AndroidManifest.xml index d2e540ed..b2d26e63 100644 --- a/src/java/kp2akeytransform/AndroidManifest.xml +++ b/src/java/kp2akeytransform/AndroidManifest.xml @@ -1,5 +1,5 @@ @@ -7,8 +7,7 @@ android:minSdkVersion="8" android:targetSdkVersion="17" /> - + \ No newline at end of file diff --git a/src/java/kp2akeytransform/bin/kp2akeytransform.jar b/src/java/kp2akeytransform/bin/kp2akeytransform.jar index 6bd07b9c..5a43a287 100644 Binary files a/src/java/kp2akeytransform/bin/kp2akeytransform.jar and b/src/java/kp2akeytransform/bin/kp2akeytransform.jar differ diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs index 03317cd5..0b7a889a 100644 --- a/src/keepass2android/PasswordActivity.cs +++ b/src/keepass2android/PasswordActivity.cs @@ -835,7 +835,7 @@ namespace keepass2android } - private MemoryStream LoadDbFile() + private MemoryStream PreloadDbFile() { if (KdbpFile.GetFormatToUse(_ioConnection) == KdbxFormat.ProtocolBuffers) { @@ -998,7 +998,7 @@ namespace keepass2android if (_loadDbTask == null && _prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true)) { // Create task to kick off file loading while the user enters the password - _loadDbTask = Task.Factory.StartNew(LoadDbFile); + _loadDbTask = Task.Factory.StartNew(PreloadDbFile); } } } diff --git a/src/keepass2android/app/App.cs b/src/keepass2android/app/App.cs index 43e02024..0cab5b8b 100644 --- a/src/keepass2android/app/App.cs +++ b/src/keepass2android/app/App.cs @@ -24,6 +24,7 @@ using Android.Graphics.Drawables; using Android.OS; using Android.Runtime; using Android.Widget; +using KeePassLib; using KeePassLib.Cryptography.Cipher; using KeePassLib.Keys; using KeePassLib.Serialization; @@ -108,9 +109,9 @@ namespace keepass2android Application.Context.SendBroadcast(new Intent(Intents.DatabaseLocked)); } - public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger) + public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseLoader databaseLoader) { - _db.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger); + _db.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseLoader); UpdateOngoingNotification(); } diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index de446bc2..8447d5e7 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -30,7 +30,7 @@ full false bin\Debug - DEBUG;EXCLUDE_TWOFISH;INCLUDE_KEYBOARD;INCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE + DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE prompt 4 False @@ -911,4 +911,10 @@ + + + + + + \ No newline at end of file diff --git a/src/monodroid-unittesting/MonoDroidUnitTesting/Frontends/GuiTestRunnerActivity.cs b/src/monodroid-unittesting/MonoDroidUnitTesting/Frontends/GuiTestRunnerActivity.cs index 4b5673f6..b0dabb04 100644 --- a/src/monodroid-unittesting/MonoDroidUnitTesting/Frontends/GuiTestRunnerActivity.cs +++ b/src/monodroid-unittesting/MonoDroidUnitTesting/Frontends/GuiTestRunnerActivity.cs @@ -65,7 +65,7 @@ namespace MonoDroidUnitTesting { protected override void OnStart() { base.OnStart(); - new Handler().Post(this.RunTests); + //new Handler().Post(this.RunTests); } protected virtual void OnTestRunStarted() { } @@ -171,6 +171,9 @@ namespace MonoDroidUnitTesting { protected override void OnResume() { base.OnResume(); + TestRunner = null; + new Handler().Post(this.RunTests); + if (TestRunner != null) { // Only remember this view if the test run finished and therefore the previous activity has been restored. ISharedPreferencesEditor e = GetPreferences().Edit();