first version to have multiple databases open at the same time. needs testing and bug fixing.
This commit is contained in:
@@ -485,12 +485,6 @@ namespace KeePassLib
|
||||
set { m_pbHashOfLastIO = value; }
|
||||
}
|
||||
|
||||
public bool UseFileTransactions
|
||||
{
|
||||
get { return m_bUseFileTransactions; }
|
||||
set { m_bUseFileTransactions = value; }
|
||||
}
|
||||
|
||||
public bool UseFileLocks
|
||||
{
|
||||
get { return m_bUseFileLocks; }
|
||||
|
@@ -360,5 +360,12 @@ namespace KeePassLib.Serialization
|
||||
m_ioCredProtMode = IOCredProtMode.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSameFileAs(IOConnectionInfo other)
|
||||
{
|
||||
if (other == null)
|
||||
return false;
|
||||
return Path == other.Path && UserName == other.UserName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Android.App;
|
||||
@@ -33,26 +34,37 @@ namespace keepass2android
|
||||
/// This also contains methods which are UI specific and should be replacable for testing.
|
||||
public interface IKp2aApp : ICertificateValidationHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Locks the currently open database, quicklocking if available (unless false is passed for allowQuickUnlock)
|
||||
/// </summary>
|
||||
void LockDatabase(bool allowQuickUnlock = true);
|
||||
/// <summary>
|
||||
/// Locks all currently open databases, quicklocking if available (unless false is passed for allowQuickUnlock)
|
||||
/// </summary>
|
||||
void Lock(bool allowQuickUnlock);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the specified data as the currently open database, as unlocked.
|
||||
/// </summary>
|
||||
void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey,
|
||||
ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current database
|
||||
/// </summary>
|
||||
Database GetDb();
|
||||
/// <summary>
|
||||
/// Loads the specified data as the currently open database, as unlocked.
|
||||
/// </summary>
|
||||
Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Tell the app that the file from ioc was opened with keyfile.
|
||||
/// </summary>
|
||||
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, string displayName = "");
|
||||
|
||||
HashSet<PwGroup> DirtyGroups { get; }
|
||||
|
||||
void MarkAllGroupsAsDirty();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current database
|
||||
/// </summary>
|
||||
Database CurrentDb { get; }
|
||||
|
||||
IEnumerable<Database> OpenDatabases { get; }
|
||||
void CloseDatabase(Database db);
|
||||
|
||||
Database FindDatabaseForGroupId(PwUuid groupKey);
|
||||
Database FindDatabaseForEntryId(PwUuid entryId);
|
||||
|
||||
/// <summary>
|
||||
/// Tell the app that the file from ioc was opened with keyfile.
|
||||
/// </summary>
|
||||
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile, string displayName = "");
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new database and returns it
|
||||
@@ -111,6 +123,10 @@ namespace keepass2android
|
||||
bool CheckForDuplicateUuids { get; }
|
||||
#if !NoNet
|
||||
ICertificateErrorHandler CertificateErrorHandler { get; }
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -90,8 +90,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="database\CheckDatabaseForChanges.cs" />
|
||||
<Compile Include="database\edit\AddTemplateEntries.cs" />
|
||||
<Compile Include="database\edit\ChangeTemplateIds.cs" />
|
||||
<Compile Include="database\edit\CopyEntry.cs" />
|
||||
<Compile Include="database\edit\DeleteMultipleItems.cs" />
|
||||
<Compile Include="database\edit\DeleteMultipleItemsFromOneDatabase.cs" />
|
||||
<Compile Include="database\edit\EditGroup.cs" />
|
||||
<Compile Include="database\edit\MoveElements.cs" />
|
||||
<Compile Include="database\KdbDatabaseFormat.cs" />
|
||||
|
@@ -23,7 +23,7 @@ namespace keepass2android
|
||||
/// <summary>
|
||||
/// EqualityComparer implementation to compare PwGroups based on their Id
|
||||
/// </summary>
|
||||
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
|
||||
public class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
|
||||
{
|
||||
#region IEqualityComparer implementation
|
||||
public bool Equals (PwGroup x, PwGroup y)
|
||||
|
@@ -86,6 +86,11 @@ namespace keepass2android
|
||||
ReadOnlyReason_PreKitKat,
|
||||
ReadOnlyReason_ReadOnlyFlag,
|
||||
ReadOnlyReason_ReadOnlyKitKat,
|
||||
ReadOnlyReason_LocalBackup
|
||||
ReadOnlyReason_LocalBackup,
|
||||
UpdatingTemplateIds,
|
||||
ChangleLegacyTemplateIds_Message,
|
||||
ChangleLegacyTemplateIds_Title,
|
||||
Ok,
|
||||
cancel
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
IOConnectionInfo ioc = _app.GetDb().Ioc;
|
||||
IOConnectionInfo ioc = _app.CurrentDb.Ioc;
|
||||
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
||||
if (fileStorage is CachingFileStorage)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ namespace keepass2android
|
||||
hashingRemoteStream.CopyTo(remoteData);
|
||||
hashingRemoteStream.Close();
|
||||
|
||||
if (!MemUtil.ArraysEqual(_app.GetDb().KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
|
||||
if (!MemUtil.ArraysEqual(_app.CurrentDb.KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
|
||||
{
|
||||
_app.TriggerReload(_context);
|
||||
Finish(true);
|
||||
|
@@ -38,7 +38,6 @@ namespace keepass2android
|
||||
|
||||
public Dictionary<PwUuid, PwGroup> Groups = new Dictionary<PwUuid, PwGroup>(new PwUuidEqualityComparer());
|
||||
public Dictionary<PwUuid, PwEntry> Entries = new Dictionary<PwUuid, PwEntry>(new PwUuidEqualityComparer());
|
||||
public HashSet<PwGroup> Dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
|
||||
public PwGroup Root;
|
||||
public PwDatabase KpDatabase;
|
||||
public IOConnectionInfo Ioc
|
||||
@@ -49,11 +48,6 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information about the last opened entry. Includes the entry but also transformed fields.
|
||||
/// </summary>
|
||||
public PwEntryOutput LastOpenedEntry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// if an OTP key was used, this property tells the location of the OTP auxiliary file.
|
||||
/// Must be set after loading.
|
||||
@@ -74,16 +68,11 @@ namespace keepass2android
|
||||
CanWrite = true; //default
|
||||
}
|
||||
|
||||
private bool _reloadRequested;
|
||||
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
|
||||
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
|
||||
|
||||
public bool ReloadRequested
|
||||
{
|
||||
get { return _reloadRequested; }
|
||||
set { _reloadRequested = value; }
|
||||
}
|
||||
public bool ReloadRequested { get; set; }
|
||||
|
||||
public bool DidOpenFileChange()
|
||||
public bool DidOpenFileChange()
|
||||
{
|
||||
return _app.GetFileStorage(Ioc).CheckForFileChangeFast(Ioc, LastFileVersion);
|
||||
}
|
||||
@@ -195,8 +184,7 @@ namespace keepass2android
|
||||
|
||||
public void SaveData() {
|
||||
|
||||
KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions);
|
||||
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions))
|
||||
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
|
||||
{
|
||||
DatabaseFormat.Save(KpDatabase, trans.OpenFile());
|
||||
|
||||
@@ -243,14 +231,6 @@ namespace keepass2android
|
||||
PopulateGlobals(currentGroup, _app.CheckForDuplicateUuids);
|
||||
}
|
||||
|
||||
public void MarkAllGroupsAsDirty() {
|
||||
foreach ( PwGroup group in Groups.Values ) {
|
||||
Dirty.Add(group);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@@ -14,13 +14,13 @@ namespace keepass2android
|
||||
public class PwEntryOutput
|
||||
{
|
||||
private readonly PwEntry _entry;
|
||||
private readonly PwDatabase _db;
|
||||
private readonly Database _db;
|
||||
private readonly ProtectedStringDictionary _outputStrings = new ProtectedStringDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the PwEntryOutput by replacing the placeholders
|
||||
/// </summary>
|
||||
public PwEntryOutput(PwEntry entry, PwDatabase db)
|
||||
public PwEntryOutput(PwEntry entry, Database db)
|
||||
{
|
||||
_entry = entry;
|
||||
_db = db;
|
||||
@@ -34,7 +34,7 @@ namespace keepass2android
|
||||
string GetStringAndReplacePlaceholders(string key)
|
||||
{
|
||||
String value = Entry.Strings.ReadSafe(key);
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, _db, SprCompileFlags.All));
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, _db.KpDatabase, SprCompileFlags.All));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,7 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
IOConnectionInfo ioc = _app.GetDb().Ioc;
|
||||
IOConnectionInfo ioc = _app.CurrentDb.Ioc;
|
||||
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
||||
if (!(fileStorage is CachingFileStorage))
|
||||
{
|
||||
@@ -70,10 +70,10 @@ namespace keepass2android
|
||||
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
|
||||
}
|
||||
_saveDb = null;
|
||||
}), false, remoteData);
|
||||
}), _app.CurrentDb, false, remoteData);
|
||||
_saveDb.Run();
|
||||
|
||||
_app.GetDb().MarkAllGroupsAsDirty();
|
||||
_app.MarkAllGroupsAsDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ namespace keepass2android
|
||||
public class AddEntry : RunnableOnFinish {
|
||||
protected Database Db
|
||||
{
|
||||
get { return _app.GetDb(); }
|
||||
get { return _app.CurrentDb; }
|
||||
}
|
||||
|
||||
private readonly IKp2aApp _app;
|
||||
@@ -43,7 +43,7 @@ namespace keepass2android
|
||||
_app = app;
|
||||
_entry = entry;
|
||||
|
||||
_onFinishToRun = new AfterAdd(ctx, app.GetDb(), entry, OnFinishToRun);
|
||||
_onFinishToRun = new AfterAdd(ctx, app.CurrentDb, entry, app,OnFinishToRun);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace keepass2android
|
||||
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -68,12 +68,13 @@ namespace keepass2android
|
||||
private class AfterAdd : OnFinish {
|
||||
private readonly Database _db;
|
||||
private readonly PwEntry _entry;
|
||||
private readonly IKp2aApp _app;
|
||||
|
||||
public AfterAdd(Activity activity, Database db, PwEntry entry, OnFinish finish):base(activity, finish) {
|
||||
public AfterAdd(Activity activity, Database db, PwEntry entry, IKp2aApp app, OnFinish finish):base(activity, finish) {
|
||||
_db = db;
|
||||
_entry = entry;
|
||||
|
||||
}
|
||||
_app = app;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -83,7 +84,7 @@ namespace keepass2android
|
||||
PwGroup parent = _entry.ParentGroup;
|
||||
|
||||
// Mark parent group dirty
|
||||
_db.Dirty.Add(parent);
|
||||
_app.DirtyGroups.Add(parent);
|
||||
|
||||
// Add entry to global
|
||||
_db.Entries[_entry.Uuid] = _entry;
|
||||
|
@@ -26,9 +26,12 @@ namespace keepass2android
|
||||
public class AddGroup : RunnableOnFinish {
|
||||
internal Database Db
|
||||
{
|
||||
get { return _app.GetDb(); }
|
||||
get { return _app.CurrentDb; }
|
||||
}
|
||||
private IKp2aApp _app;
|
||||
|
||||
public IKp2aApp App { get => _app; }
|
||||
|
||||
private IKp2aApp _app;
|
||||
private readonly String _name;
|
||||
private readonly int _iconId;
|
||||
private readonly PwUuid _groupCustomIconId;
|
||||
@@ -69,7 +72,7 @@ namespace keepass2android
|
||||
Parent.AddGroup(Group, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, DontSave);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, DontSave);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -86,7 +89,7 @@ namespace keepass2android
|
||||
|
||||
if ( Success ) {
|
||||
// Mark parent group dirty
|
||||
_addGroup.Db.Dirty.Add(_addGroup.Parent);
|
||||
_addGroup.App.DirtyGroups.Add(_addGroup.Parent);
|
||||
|
||||
// Add group to global list
|
||||
_addGroup.Db.Groups[_addGroup.Group.Uuid] = _addGroup.Group;
|
||||
|
@@ -28,7 +28,7 @@ namespace keepass2android
|
||||
{
|
||||
public class AddTemplateEntries : RunnableOnFinish {
|
||||
|
||||
class TemplateEntry
|
||||
public class TemplateEntry
|
||||
{
|
||||
public UiStringKey Title { get; set; }
|
||||
public PwIcon Icon { get; set; }
|
||||
@@ -47,11 +47,12 @@ namespace keepass2android
|
||||
void AddToEntry(IKp2aApp app, PwEntry entry, int position);
|
||||
}
|
||||
|
||||
internal enum FieldType
|
||||
public enum FieldType
|
||||
{
|
||||
Inline, ProtectedInline
|
||||
}
|
||||
internal enum SpecialFieldKey
|
||||
|
||||
public enum SpecialFieldKey
|
||||
{
|
||||
ExpDate, OverrideUrl, Tags
|
||||
}
|
||||
@@ -125,7 +126,7 @@ namespace keepass2android
|
||||
|
||||
protected Database Db
|
||||
{
|
||||
get { return _app.GetDb(); }
|
||||
get { return _app.CurrentDb; }
|
||||
}
|
||||
|
||||
private readonly IKp2aApp _app;
|
||||
@@ -140,7 +141,7 @@ namespace keepass2android
|
||||
//_onFinishToRun = new AfterAdd(this, OnFinishToRun);
|
||||
}
|
||||
|
||||
static readonly List<TemplateEntry> TemplateEntries = new List<TemplateEntry>()
|
||||
public static readonly List<TemplateEntry> TemplateEntries = new List<TemplateEntry>()
|
||||
{
|
||||
new TemplateEntry()
|
||||
{
|
||||
@@ -285,12 +286,23 @@ namespace keepass2android
|
||||
|
||||
};
|
||||
|
||||
public static bool ContainsAllTemplates(IKp2aApp app)
|
||||
public static bool ContainsAllTemplates(Database db)
|
||||
{
|
||||
return TemplateEntries.All(t => app.GetDb().Entries.ContainsKey(t.Uuid));
|
||||
return TemplateEntries.All(t =>
|
||||
{
|
||||
string hexId = t.Uuid.ToHexString();
|
||||
|
||||
return db.Entries.Any(kvp => kvp.Key.Equals(t.Uuid) ||
|
||||
kvp.Value.Strings.ReadSafe(TemplateIdStringKey) == hexId);
|
||||
});
|
||||
}
|
||||
|
||||
public override void Run() {
|
||||
public static string TemplateIdStringKey
|
||||
{
|
||||
get { return "KP2A_TemplateId"; }
|
||||
}
|
||||
|
||||
public override void Run() {
|
||||
StatusLogger.UpdateMessage(UiStringKey.AddingEntry);
|
||||
|
||||
List<PwEntry> addedEntries;
|
||||
@@ -298,10 +310,10 @@ namespace keepass2android
|
||||
|
||||
if (addedEntries.Any())
|
||||
{
|
||||
_app.GetDb().Dirty.Add(templateGroup);
|
||||
_app.DirtyGroups.Add(templateGroup);
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -315,37 +327,38 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
PwGroup templateGroup;
|
||||
if (!_app.GetDb().Groups.TryGetValue(_app.GetDb().KpDatabase.EntryTemplatesGroup, out templateGroup))
|
||||
if (!_app.CurrentDb.Groups.TryGetValue(_app.CurrentDb.KpDatabase.EntryTemplatesGroup, out templateGroup))
|
||||
{
|
||||
//create template group
|
||||
templateGroup = new PwGroup(true, true, _app.GetResourceString(UiStringKey.TemplateGroupName), PwIcon.Folder);
|
||||
_app.GetDb().KpDatabase.RootGroup.AddGroup(templateGroup, true);
|
||||
_app.GetDb().KpDatabase.EntryTemplatesGroup = templateGroup.Uuid;
|
||||
_app.GetDb().KpDatabase.EntryTemplatesGroupChanged = DateTime.Now;
|
||||
_app.GetDb().Dirty.Add(_app.GetDb().KpDatabase.RootGroup);
|
||||
_app.GetDb().Groups[templateGroup.Uuid] = templateGroup;
|
||||
_app.CurrentDb.KpDatabase.RootGroup.AddGroup(templateGroup, true);
|
||||
_app.CurrentDb.KpDatabase.EntryTemplatesGroup = templateGroup.Uuid;
|
||||
_app.CurrentDb.KpDatabase.EntryTemplatesGroupChanged = DateTime.Now;
|
||||
_app.DirtyGroups.Add(_app.CurrentDb.KpDatabase.RootGroup);
|
||||
_app.CurrentDb.Groups[templateGroup.Uuid] = templateGroup;
|
||||
}
|
||||
addedEntries = new List<PwEntry>();
|
||||
|
||||
foreach (var template in TemplateEntries)
|
||||
{
|
||||
if (_app.GetDb().Entries.ContainsKey(template.Uuid))
|
||||
if (_app.CurrentDb.Entries.ContainsKey(template.Uuid))
|
||||
continue;
|
||||
PwEntry entry = CreateEntry(template);
|
||||
templateGroup.AddEntry(entry, true);
|
||||
addedEntries.Add(entry);
|
||||
_app.GetDb().Entries[entry.Uuid] = entry;
|
||||
_app.CurrentDb.Entries[entry.Uuid] = entry;
|
||||
}
|
||||
return templateGroup;
|
||||
}
|
||||
|
||||
private PwEntry CreateEntry(TemplateEntry template)
|
||||
{
|
||||
PwEntry entry = new PwEntry(false, true);
|
||||
entry.Uuid = template.Uuid;
|
||||
PwEntry entry = new PwEntry(true, true);
|
||||
|
||||
entry.IconId = template.Icon;
|
||||
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, _app.GetResourceString(template.Title)));
|
||||
entry.Strings.Set("_etm_template", new ProtectedString(false, "1"));
|
||||
entry.Strings.Set(TemplateIdStringKey, new ProtectedString(false, template.Uuid.ToHexString()));
|
||||
int position = 0;
|
||||
foreach (var field in template.Fields)
|
||||
{
|
||||
@@ -375,6 +388,10 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
public static bool IsTemplateId(PwUuid pwUuid)
|
||||
{
|
||||
return TemplateEntries.Any(te => te.Uuid.Equals(pwUuid));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
76
src/Kp2aBusinessLogic/database/edit/ChangeTemplateIds.cs
Normal file
76
src/Kp2aBusinessLogic/database/edit/ChangeTemplateIds.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
|
||||
namespace keepass2android.database.edit
|
||||
{
|
||||
public class ChangeTemplateIds: RunnableOnFinish
|
||||
{
|
||||
private readonly IKp2aApp _app;
|
||||
private readonly Database _db;
|
||||
private string _etmTemplateUuid { get { return "_etm_template_uuid"; } }
|
||||
public static string TemplateIdStringKey
|
||||
{
|
||||
get { return "KP2A_TemplateId"; }
|
||||
}
|
||||
|
||||
public ChangeTemplateIds(Activity activeActivity, IKp2aApp app, Database db, OnFinish finish) : base(activeActivity, finish)
|
||||
{
|
||||
_app = app;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.UpdatingTemplateIds);
|
||||
Dictionary<string, string> uuidMap = new Dictionary<string, string>();
|
||||
foreach (var templateEntry in AddTemplateEntries.TemplateEntries)
|
||||
{
|
||||
PwEntry entry;
|
||||
if (_db.Entries.TryGetValue(templateEntry.Uuid, out entry))
|
||||
{
|
||||
PwUuid oldUuid = entry.Uuid;
|
||||
entry.Uuid = new PwUuid(true);
|
||||
uuidMap[oldUuid.ToHexString()] = entry.Uuid.ToHexString();
|
||||
entry.Strings.Set(TemplateIdStringKey,new ProtectedString(false, oldUuid.ToHexString()));
|
||||
_db.Entries.Remove(oldUuid);
|
||||
_db.Entries[entry.Uuid] = entry;
|
||||
}
|
||||
}
|
||||
foreach (var entry in _db.Entries.Values)
|
||||
{
|
||||
string templateUuid = entry.Strings.ReadSafe(_etmTemplateUuid);
|
||||
if (templateUuid != null)
|
||||
{
|
||||
string newTemplateUuid;
|
||||
if (uuidMap.TryGetValue(templateUuid, out newTemplateUuid))
|
||||
{
|
||||
entry.Strings.Set(_etmTemplateUuid, new ProtectedString(false, newTemplateUuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uuidMap.Any())
|
||||
{
|
||||
SaveDb save = new SaveDb( ActiveActivity, _app, _db, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnFinishToRun?.Run();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -84,7 +84,7 @@ namespace keepass2android
|
||||
addTemplates.AddTemplates(out addedEntries);
|
||||
|
||||
// Commit changes
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, _dontSave);
|
||||
SaveDb save = new SaveDb(_ctx, _app, db, OnFinishToRun, _dontSave);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
_onFinishToRun = null;
|
||||
save.Run();
|
||||
|
@@ -31,7 +31,7 @@ namespace keepass2android
|
||||
|
||||
public DeleteEntry(Activity activiy, IKp2aApp app, PwEntry entry, OnFinish finish):base(activiy, finish, app) {
|
||||
Ctx = activiy;
|
||||
Db = app.GetDb();
|
||||
Db = app.FindDatabaseForEntryId(entry.Uuid);
|
||||
_entry = entry;
|
||||
|
||||
}
|
||||
@@ -40,7 +40,7 @@ namespace keepass2android
|
||||
{
|
||||
get
|
||||
{
|
||||
return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_entry.ParentGroup);
|
||||
return Db.DatabaseFormat.CanRecycle && CanRecycleGroup(_entry.ParentGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,7 +47,7 @@ namespace keepass2android
|
||||
*/
|
||||
private void SetMembers(Activity activity, IKp2aApp app, PwGroup group, bool dontSave)
|
||||
{
|
||||
base.SetMembers(activity, app.GetDb());
|
||||
base.SetMembers(activity, app.FindDatabaseForGroupId(group.Uuid));
|
||||
|
||||
_group = group;
|
||||
DontSave = dontSave;
|
||||
@@ -58,7 +58,7 @@ namespace keepass2android
|
||||
{
|
||||
get
|
||||
{
|
||||
return App.GetDb().DatabaseFormat.CanRecycle && CanRecycleGroup(_group);
|
||||
return Db.DatabaseFormat.CanRecycle && CanRecycleGroup(_group);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,12 +7,12 @@ using KeePassLib.Interfaces;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class DeleteMultipleItems : DeleteRunnable
|
||||
public class DeleteMultipleItemsFromOneDatabase : DeleteRunnable
|
||||
{
|
||||
private readonly List<IStructureItem> _elementsToDelete;
|
||||
private readonly bool _canRecycle;
|
||||
|
||||
public DeleteMultipleItems(Activity activity, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
|
||||
public DeleteMultipleItemsFromOneDatabase(Activity activity, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
|
||||
: base(activity, finish, app)
|
||||
{
|
||||
_elementsToDelete = elementsToDelete;
|
||||
@@ -26,7 +26,7 @@ namespace keepass2android
|
||||
private bool DetermineCanRecycle()
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "CanRecycle?");
|
||||
if (!App.GetDb().DatabaseFormat.CanRecycle)
|
||||
if (!Db.DatabaseFormat.CanRecycle)
|
||||
{
|
||||
Android.Util.Log.Debug("KP2A", "CanRecycle? No because of DB format.");
|
||||
return false;
|
@@ -130,6 +130,7 @@ namespace keepass2android
|
||||
DeletePermanently = true;
|
||||
ProgressTask pt = new ProgressTask(App, Ctx, this);
|
||||
pt.Run();
|
||||
|
||||
},
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
@@ -215,11 +216,11 @@ namespace keepass2android
|
||||
if (success)
|
||||
{
|
||||
foreach (var g in touchedGroups)
|
||||
Db.Dirty.Add(g);
|
||||
App.DirtyGroups.Add(g);
|
||||
foreach (var g in permanentlyDeletedGroups)
|
||||
{
|
||||
//remove groups from global lists if present there
|
||||
Db.Dirty.Remove(g);
|
||||
//remove groups from global lists if present there
|
||||
App.DirtyGroups.Remove(g);
|
||||
Db.Groups.Remove(g.Uuid);
|
||||
}
|
||||
|
||||
@@ -227,12 +228,12 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
// Let's not bother recovering from a failure to save. It is too much work.
|
||||
App.LockDatabase(false);
|
||||
App.Lock(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
|
||||
// Commit database
|
||||
SaveDb save = new SaveDb(Ctx, App, OnFinishToRun, false);
|
||||
SaveDb save = new SaveDb(Ctx, App, Db, OnFinishToRun, false);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
|
||||
|
@@ -26,9 +26,12 @@ namespace keepass2android
|
||||
public class EditGroup : RunnableOnFinish {
|
||||
internal Database Db
|
||||
{
|
||||
get { return _app.GetDb(); }
|
||||
get { return _app.FindDatabaseForGroupId(Group.Uuid); }
|
||||
}
|
||||
private IKp2aApp _app;
|
||||
|
||||
public IKp2aApp App { get => _app; }
|
||||
|
||||
private IKp2aApp _app;
|
||||
private readonly String _name;
|
||||
private readonly PwIcon _iconId;
|
||||
private readonly PwUuid _customIconId;
|
||||
@@ -57,7 +60,7 @@ namespace keepass2android
|
||||
Group.Touch(true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
||||
SaveDb save = new SaveDb(_ctx, _app, Db, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -76,10 +79,10 @@ namespace keepass2android
|
||||
|
||||
if ( Success ) {
|
||||
// Mark parent group dirty
|
||||
_editGroup.Db.Dirty.Add(_editGroup.Group.ParentGroup);
|
||||
_editGroup.App.DirtyGroups.Add(_editGroup.Group.ParentGroup);
|
||||
} else
|
||||
{
|
||||
_editGroup._app.LockDatabase(false);
|
||||
_editGroup._app.Lock(false);
|
||||
}
|
||||
|
||||
base.Run();
|
||||
|
@@ -21,6 +21,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using keepass2android.database.edit;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
@@ -48,6 +49,7 @@ namespace keepass2android
|
||||
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
||||
}
|
||||
|
||||
protected bool success = false;
|
||||
|
||||
public override void Run()
|
||||
{
|
||||
@@ -78,6 +80,10 @@ namespace keepass2android
|
||||
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
|
||||
_format = new KdbxDatabaseFormat(KdbpFile.GetFormatToUse(_ioc));
|
||||
TryLoad(databaseStream);
|
||||
|
||||
|
||||
|
||||
success = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -125,7 +131,7 @@ namespace keepass2android
|
||||
/// </summary>
|
||||
public Exception Exception { get; set; }
|
||||
|
||||
private void TryLoad(MemoryStream databaseStream)
|
||||
Database TryLoad(MemoryStream databaseStream)
|
||||
{
|
||||
//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.
|
||||
@@ -138,19 +144,89 @@ namespace keepass2android
|
||||
//now let's go:
|
||||
try
|
||||
{
|
||||
_app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format);
|
||||
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format);
|
||||
Kp2aLog.Log("LoadDB OK");
|
||||
|
||||
//make sure the stored access time for the actual file is more recent than that of its backup
|
||||
Thread.Sleep(10);
|
||||
SaveFileData(_ioc, _keyfileOrProvider);
|
||||
|
||||
Finish(true, _format.SuccessMessage);
|
||||
|
||||
bool hasLegacyTemplateIds = false;
|
||||
//make sure we never have entries with same Uuids
|
||||
foreach (var entryKey in newDb.Entries.Keys)
|
||||
{
|
||||
foreach (Database otherDb in _app.OpenDatabases)
|
||||
{
|
||||
if (otherDb == newDb)
|
||||
continue;
|
||||
if (otherDb.Entries.ContainsKey(entryKey))
|
||||
{
|
||||
if (AddTemplateEntries.IsTemplateId(entryKey))
|
||||
{
|
||||
hasLegacyTemplateIds = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_app.CloseDatabase(newDb);
|
||||
throw new Exception("Database contains entry id " + entryKey.ToHexString() + "(" +
|
||||
newDb.Entries[entryKey].Strings.ReadSafe(PwDefs.TitleField)
|
||||
+ ") which is already contained in " +
|
||||
_app.GetFileStorage(otherDb.Ioc).GetDisplayName(otherDb.Ioc) +
|
||||
"! Please close the other database before opening this one.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var groupKey in newDb.Groups.Keys)
|
||||
{
|
||||
foreach (Database otherDb in _app.OpenDatabases)
|
||||
{
|
||||
if (otherDb == newDb)
|
||||
continue;
|
||||
if (otherDb.Groups.ContainsKey(groupKey))
|
||||
{
|
||||
throw new Exception("Database contains group id " + groupKey.ToHexString() + "(" +
|
||||
newDb.Groups[groupKey].Name + ") which is already contained in " +
|
||||
_app.GetFileStorage(otherDb.Ioc).GetDisplayName(otherDb.Ioc) +
|
||||
"! Please close the other database before opening this one.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLegacyTemplateIds)
|
||||
{
|
||||
_app.AskYesNoCancel(UiStringKey.ChangleLegacyTemplateIds_Title, UiStringKey.ChangleLegacyTemplateIds_Message,UiStringKey.Ok, UiStringKey.cancel,
|
||||
/*yes*/
|
||||
(sender, args) =>
|
||||
{
|
||||
ChangeTemplateIds cti = new ChangeTemplateIds(ActiveActivity, _app, newDb, new ActionOnFinish(ActiveActivity, (b, message, activity) => Finish(b, message)));
|
||||
cti.Run();
|
||||
},
|
||||
/*no*/
|
||||
(sender, args) =>
|
||||
{
|
||||
_app.CloseDatabase(newDb);
|
||||
Finish(false);
|
||||
},
|
||||
null,
|
||||
ActiveActivity
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
Finish(true, _format.SuccessMessage);
|
||||
return newDb;
|
||||
}
|
||||
catch (OldFormatException)
|
||||
{
|
||||
_format = new KdbDatabaseFormat(_app);
|
||||
TryLoad(databaseStream);
|
||||
return TryLoad(databaseStream);
|
||||
}
|
||||
catch (InvalidCompositeKeyException)
|
||||
{
|
||||
@@ -162,7 +238,7 @@ namespace keepass2android
|
||||
//retry without password:
|
||||
_compositeKey.RemoveUserKey(passwordKey);
|
||||
//retry:
|
||||
TryLoad(databaseStream);
|
||||
return TryLoad(databaseStream);
|
||||
}
|
||||
else throw;
|
||||
}
|
||||
|
@@ -53,8 +53,8 @@ namespace keepass2android.database.edit
|
||||
foreach (var elementToMove in _elementsToMove)
|
||||
{
|
||||
|
||||
_app.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
||||
|
||||
_app.DirtyGroups.Add(elementToMove.ParentGroup);
|
||||
//TODO is this safe when transferring between databases?
|
||||
PwGroup pgParent = elementToMove.ParentGroup;
|
||||
if (pgParent != _targetGroup)
|
||||
{
|
||||
@@ -87,12 +87,15 @@ namespace keepass2android.database.edit
|
||||
{
|
||||
if (!success)
|
||||
{ // Let's not bother recovering from a failure.
|
||||
_app.LockDatabase(false);
|
||||
_app.Lock(false);
|
||||
}
|
||||
}, OnFinishToRun);
|
||||
|
||||
//Unchecked
|
||||
//TODO save the right database
|
||||
|
||||
// Save
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, false);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, false);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
|
@@ -34,7 +34,8 @@ namespace keepass2android
|
||||
|
||||
public class SaveDb : RunnableOnFinish {
|
||||
private readonly IKp2aApp _app;
|
||||
private readonly bool _dontSave;
|
||||
private readonly Database _db;
|
||||
private readonly bool _dontSave;
|
||||
|
||||
/// <summary>
|
||||
/// stream for reading the data from the original file. If this is set to a non-null value, we know we need to sync
|
||||
@@ -43,9 +44,10 @@ namespace keepass2android
|
||||
private readonly Context _ctx;
|
||||
private Thread _workerThread;
|
||||
|
||||
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave)
|
||||
public SaveDb(Activity ctx, IKp2aApp app, Database db, OnFinish finish, bool dontSave)
|
||||
: base(ctx, finish)
|
||||
{
|
||||
_db = db;
|
||||
_ctx = ctx;
|
||||
_app = app;
|
||||
_dontSave = dontSave;
|
||||
@@ -59,21 +61,23 @@ namespace keepass2android
|
||||
/// <param name="finish"></param>
|
||||
/// <param name="dontSave"></param>
|
||||
/// <param name="streamForOrigFile">Stream for reading the data from the (changed) original location</param>
|
||||
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave, Stream streamForOrigFile)
|
||||
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, Database db, bool dontSave, Stream streamForOrigFile)
|
||||
: base(ctx, finish)
|
||||
{
|
||||
_db = db;
|
||||
_ctx = ctx;
|
||||
_app = app;
|
||||
_dontSave = dontSave;
|
||||
_streamForOrigFile = streamForOrigFile;
|
||||
}
|
||||
|
||||
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish)
|
||||
public SaveDb(Activity ctx, IKp2aApp app, Database db, OnFinish finish)
|
||||
: base(ctx, finish)
|
||||
{
|
||||
_ctx = ctx;
|
||||
_app = app;
|
||||
_dontSave = false;
|
||||
_db = db;
|
||||
_dontSave = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +88,7 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_app.GetDb().CanWrite == false)
|
||||
if (_db.CanWrite == false)
|
||||
{
|
||||
//this should only happen if there is a problem in the UI so that the user sees an edit interface.
|
||||
Finish(false,"Cannot save changes. File is read-only!");
|
||||
@@ -92,13 +96,13 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
StatusLogger.UpdateMessage(UiStringKey.saving_database);
|
||||
IOConnectionInfo ioc = _app.GetDb().Ioc;
|
||||
IOConnectionInfo ioc = _db.Ioc;
|
||||
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
||||
|
||||
if (_streamForOrigFile == null)
|
||||
{
|
||||
if ((!_app.GetBooleanPreference(PreferenceKey.CheckForFileChangesOnSave))
|
||||
|| (_app.GetDb().KpDatabase.HashOfFileOnDisk == null)) //first time saving
|
||||
|| (_db.KpDatabase.HashOfFileOnDisk == null)) //first time saving
|
||||
{
|
||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||
Finish(true);
|
||||
@@ -109,8 +113,8 @@ namespace keepass2android
|
||||
|
||||
if (
|
||||
(_streamForOrigFile != null)
|
||||
|| fileStorage.CheckForFileChangeFast(ioc, _app.GetDb().LastFileVersion) //first try to use the fast change detection
|
||||
|| (FileHashChanged(ioc, _app.GetDb().KpDatabase.HashOfFileOnDisk) == FileHashChange.Changed) //if that fails, hash the file and compare:
|
||||
|| fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion) //first try to use the fast change detection
|
||||
|| (FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) == FileHashChange.Changed) //if that fails, hash the file and compare:
|
||||
)
|
||||
{
|
||||
|
||||
@@ -217,13 +221,13 @@ namespace keepass2android
|
||||
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.SynchronizingDatabase));
|
||||
|
||||
PwDatabase pwImp = new PwDatabase();
|
||||
PwDatabase pwDatabase = _app.GetDb().KpDatabase;
|
||||
PwDatabase pwDatabase = _db.KpDatabase;
|
||||
pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey);
|
||||
pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep();
|
||||
pwImp.MasterKey = pwDatabase.MasterKey;
|
||||
var stream = GetStreamForBaseFile(fileStorage, ioc);
|
||||
|
||||
_app.GetDb().DatabaseFormat.PopulateDatabaseFromStream(pwImp, stream, null);
|
||||
_db.DatabaseFormat.PopulateDatabaseFromStream(pwImp, stream, null);
|
||||
|
||||
|
||||
pwDatabase.MergeIn(pwImp, PwMergeMethod.Synchronize, null);
|
||||
@@ -249,8 +253,8 @@ namespace keepass2android
|
||||
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
|
||||
{
|
||||
StatusLogger.UpdateSubMessage("");
|
||||
_app.GetDb().SaveData();
|
||||
_app.GetDb().LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
||||
_db.SaveData();
|
||||
_db.LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
||||
}
|
||||
|
||||
public byte[] HashOriginalFile(IOConnectionInfo iocFile)
|
||||
|
@@ -52,7 +52,7 @@ namespace keepass2android
|
||||
public override void Run ()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.SettingPassword);
|
||||
PwDatabase pm = _app.GetDb().KpDatabase;
|
||||
PwDatabase pm = _app.CurrentDb.KpDatabase;
|
||||
CompositeKey newKey = new CompositeKey ();
|
||||
if (String.IsNullOrEmpty (_password) == false) {
|
||||
newKey.AddUserKey (new KcpPassword (_password));
|
||||
@@ -74,7 +74,7 @@ namespace keepass2android
|
||||
|
||||
// Save Database
|
||||
_onFinishToRun = new AfterSave(ActiveActivity, previousKey, previousMasterKeyChanged, pm, OnFinishToRun);
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, _dontSave);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun, _dontSave);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ namespace keepass2android
|
||||
|
||||
public override void Run() {
|
||||
// Commit to disk
|
||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
||||
SaveDb save = new SaveDb(_ctx, _app, _app.CurrentDb, OnFinishToRun);
|
||||
save.SetStatusLogger(StatusLogger);
|
||||
save.Run();
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace keepass2android
|
||||
if ( parent != null ) {
|
||||
|
||||
// Mark parent group dirty
|
||||
_app.GetDb().Dirty.Add(parent);
|
||||
_app.DirtyGroups.Add(parent);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,7 @@ namespace keepass2android
|
||||
b.SetMessage(Resource.String.killed_by_os);
|
||||
b.SetPositiveButton(Android.Resource.String.Ok, delegate
|
||||
{
|
||||
Intent i = new Intent(this, typeof(FileSelectActivity));
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
i.AddFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
|
||||
StartActivity(i);
|
||||
|
||||
|
@@ -91,7 +91,7 @@ namespace keepass2android
|
||||
public class EntryActivity : LockCloseActivity
|
||||
{
|
||||
public const String KeyEntry = "entry";
|
||||
public const String KeyRefreshPos = "refresh_pos";
|
||||
public const String KeyRefreshPos = "refresh_pos";
|
||||
public const String KeyCloseAfterCreate = "close_after_create";
|
||||
public const String KeyGroupFullPath = "groupfullpath_key";
|
||||
|
||||
@@ -107,6 +107,11 @@ namespace keepass2android
|
||||
i.PutExtra(KeyEntry, pw.Uuid.ToHexString());
|
||||
i.PutExtra(KeyRefreshPos, pos);
|
||||
|
||||
if (!App.Kp2a.CurrentDb.Entries.ContainsKey(pw.Uuid))
|
||||
{
|
||||
App.Kp2a.CurrentDb = App.Kp2a.FindDatabaseForEntryId(pw.Uuid);
|
||||
}
|
||||
|
||||
if (flags != null)
|
||||
i.SetFlags((ActivityFlags) flags);
|
||||
|
||||
@@ -167,7 +172,7 @@ namespace keepass2android
|
||||
|
||||
protected void SetupEditButtons() {
|
||||
View edit = FindViewById(Resource.Id.entry_edit);
|
||||
if (App.Kp2a.GetDb().CanWrite)
|
||||
if (App.Kp2a.CurrentDb.CanWrite)
|
||||
{
|
||||
edit.Visibility = ViewStates.Visible;
|
||||
edit.Click += (sender, e) =>
|
||||
@@ -265,9 +270,9 @@ namespace keepass2android
|
||||
|
||||
//update the Entry output in the App database and notify the CopyToClipboard service
|
||||
|
||||
if (App.Kp2a.GetDb()?.LastOpenedEntry != null)
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
{
|
||||
App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.Set(key, new ProtectedString(isProtected, value));
|
||||
App.Kp2a.LastOpenedEntry.OutputStrings.Set(key, new ProtectedString(isProtected, value));
|
||||
Intent updateKeyboardIntent = new Intent(this, typeof(CopyToClipboardService));
|
||||
updateKeyboardIntent.SetAction(Intents.UpdateKeyboard);
|
||||
updateKeyboardIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
|
||||
@@ -323,7 +328,7 @@ namespace keepass2android
|
||||
i.SetPackage(pluginPackage);
|
||||
i.PutExtra(Strings.ExtraActionData, bundleExtra);
|
||||
i.PutExtra(Strings.ExtraSender, PackageName);
|
||||
PluginHost.AddEntryToIntent(i, App.Kp2a.GetDb().LastOpenedEntry);
|
||||
PluginHost.AddEntryToIntent(i, App.Kp2a.LastOpenedEntry);
|
||||
|
||||
var menuOption = new PluginMenuOption()
|
||||
{
|
||||
@@ -389,7 +394,7 @@ namespace keepass2android
|
||||
|
||||
SetEntryView();
|
||||
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
// Likely the app has been killed exit the activity
|
||||
if (db == null || (App.Kp2a.QuickLocked))
|
||||
{
|
||||
@@ -428,7 +433,7 @@ namespace keepass2android
|
||||
|
||||
SetupEditButtons();
|
||||
|
||||
App.Kp2a.GetDb().LastOpenedEntry = new PwEntryOutput(Entry, App.Kp2a.GetDb().KpDatabase);
|
||||
App.Kp2a.LastOpenedEntry = new PwEntryOutput(Entry, App.Kp2a.CurrentDb);
|
||||
|
||||
_pluginActionReceiver = new PluginActionReceiver(this);
|
||||
RegisterReceiver(_pluginActionReceiver, new IntentFilter(Strings.ActionAddEntryAction));
|
||||
@@ -508,8 +513,8 @@ namespace keepass2android
|
||||
ViewGroup extraGroup = (ViewGroup) FindViewById(Resource.Id.extra_strings);
|
||||
bool hasExtras = false;
|
||||
IEditMode editMode = new DefaultEdit();
|
||||
if (KpEntryTemplatedEdit.IsTemplated(App.Kp2a.GetDb(), this.Entry))
|
||||
editMode = new KpEntryTemplatedEdit(App.Kp2a.GetDb(), this.Entry);
|
||||
if (KpEntryTemplatedEdit.IsTemplated(App.Kp2a.CurrentDb, this.Entry))
|
||||
editMode = new KpEntryTemplatedEdit(App.Kp2a.CurrentDb, this.Entry);
|
||||
foreach (var key in editMode.SortExtraFieldKeys(Entry.Strings.GetKeys().Where(key=> !PwDefs.IsStandardField(key))))
|
||||
{
|
||||
if (editMode.IsVisible(key))
|
||||
@@ -936,7 +941,7 @@ namespace keepass2android
|
||||
private void PopulateStandardText(List<int> viewIds, int containerViewId, String key)
|
||||
{
|
||||
String value = Entry.Strings.ReadSafe(key);
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, App.Kp2a.GetDb().KpDatabase, SprCompileFlags.All));
|
||||
value = SprEngine.Compile(value, new SprContext(Entry, App.Kp2a.CurrentDb.KpDatabase, SprCompileFlags.All));
|
||||
PopulateText(viewIds, containerViewId, value);
|
||||
_stringViews.Add(key, new StandardStringView(viewIds, containerViewId, this));
|
||||
}
|
||||
@@ -1012,7 +1017,7 @@ namespace keepass2android
|
||||
{
|
||||
((IOfflineSwitchable)fileStorage).IsOffline = false;
|
||||
}
|
||||
using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetDb().KpDatabase.UseFileTransactions))
|
||||
using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
|
||||
{
|
||||
Stream sOut = writeTransaction.OpenFile();
|
||||
|
||||
@@ -1173,7 +1178,7 @@ namespace keepass2android
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_lock:
|
||||
App.Kp2a.LockDatabase();
|
||||
App.Kp2a.Lock();
|
||||
return true;
|
||||
case Android.Resource.Id.Home:
|
||||
//Currently the action bar only displays the home button when we come from a previous activity.
|
||||
@@ -1264,7 +1269,7 @@ namespace keepass2android
|
||||
|
||||
public void AddEntryToIntent(Intent intent)
|
||||
{
|
||||
PluginHost.AddEntryToIntent(intent, App.Kp2a.GetDb().LastOpenedEntry);
|
||||
PluginHost.AddEntryToIntent(intent, App.Kp2a.LastOpenedEntry);
|
||||
}
|
||||
|
||||
public void CloseAfterTaskComplete()
|
||||
|
@@ -120,7 +120,7 @@ namespace keepass2android
|
||||
|
||||
} else
|
||||
{
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
|
||||
App.Kp2a.EntryEditActivityState = new EntryEditActivityState();
|
||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
@@ -199,7 +199,7 @@ namespace keepass2android
|
||||
|
||||
if (State.SelectedIcon)
|
||||
{
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iconButton, this, App.Kp2a.GetDb().KpDatabase, (PwIcon)State.SelectedIconId, State.SelectedCustomIconId, false);
|
||||
App.Kp2a.CurrentDb.DrawableFactory.AssignDrawableTo(iconButton, this, App.Kp2a.CurrentDb.KpDatabase, (PwIcon)State.SelectedIconId, State.SelectedCustomIconId, false);
|
||||
}
|
||||
iconButton.Click += (sender, evt) => {
|
||||
UpdateEntryFromUi(State.Entry);
|
||||
@@ -371,7 +371,7 @@ namespace keepass2android
|
||||
|
||||
private void SetAddExtraStringEnabled()
|
||||
{
|
||||
if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveCustomFields)
|
||||
if (!App.Kp2a.CurrentDb.DatabaseFormat.CanHaveCustomFields)
|
||||
((Button)FindViewById(Resource.Id.add_advanced)).Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ namespace keepass2android
|
||||
|
||||
void SaveEntry()
|
||||
{
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
EntryEditActivity act = this;
|
||||
|
||||
if (!ValidateBeforeSaving())
|
||||
@@ -498,7 +498,7 @@ namespace keepass2android
|
||||
|
||||
void UpdateEntryFromUi(PwEntry entry)
|
||||
{
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
EntryEditActivity act = this;
|
||||
|
||||
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectTitle,
|
||||
@@ -753,7 +753,7 @@ namespace keepass2android
|
||||
String generatedPassword = data.GetStringExtra("keepass2android.password.generated_password");
|
||||
|
||||
byte[] password = StrUtil.Utf8.GetBytes(generatedPassword);
|
||||
State.Entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(App.Kp2a.GetDb().KpDatabase.MemoryProtection.ProtectPassword,
|
||||
State.Entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(App.Kp2a.CurrentDb.KpDatabase.MemoryProtection.ProtectPassword,
|
||||
password));
|
||||
MemUtil.ZeroByteArray(password);
|
||||
|
||||
@@ -792,7 +792,7 @@ namespace keepass2android
|
||||
{
|
||||
String key = pair.Key;
|
||||
String label = key;
|
||||
if ((String.IsNullOrEmpty(label) || (!App.Kp2a.GetDb().DatabaseFormat.SupportsAttachmentKeys)))
|
||||
if ((String.IsNullOrEmpty(label) || (!App.Kp2a.CurrentDb.DatabaseFormat.SupportsAttachmentKeys)))
|
||||
{
|
||||
label = "<attachment>";
|
||||
}
|
||||
@@ -820,7 +820,7 @@ namespace keepass2android
|
||||
|
||||
addBinaryButton.Enabled = true;
|
||||
|
||||
if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveMultipleAttachments)
|
||||
if (!App.Kp2a.CurrentDb.DatabaseFormat.CanHaveMultipleAttachments)
|
||||
addBinaryButton.Enabled = !State.Entry.Binaries.Any();
|
||||
addBinaryButton.Click += (sender, e) =>
|
||||
{
|
||||
@@ -921,7 +921,7 @@ namespace keepass2android
|
||||
{
|
||||
if (_additionalKeys == null)
|
||||
{
|
||||
_additionalKeys = App.Kp2a.GetDb().Entries
|
||||
_additionalKeys = App.Kp2a.CurrentDb.Entries
|
||||
.Select(kvp => kvp.Value)
|
||||
.SelectMany(x => x.Strings.GetKeys().Where(k => !PwDefs.IsStandardField(k)))
|
||||
.Where(k => (k != null) && !k.StartsWith("_etm_") )
|
||||
@@ -999,7 +999,7 @@ namespace keepass2android
|
||||
{
|
||||
_editModeHiddenViews = new List<View>();
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(currIconButton, this, App.Kp2a.GetDb().KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid, false);
|
||||
App.Kp2a.CurrentDb.DrawableFactory.AssignDrawableTo(currIconButton, this, App.Kp2a.CurrentDb.KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid, false);
|
||||
|
||||
PopulateText(Resource.Id.entry_title, State.Entry.Strings.ReadSafe (PwDefs.TitleField));
|
||||
PopulateText(Resource.Id.entry_user_name, State.Entry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||
@@ -1028,7 +1028,7 @@ namespace keepass2android
|
||||
|
||||
PopulateBinaries();
|
||||
|
||||
if (App.Kp2a.GetDb().DatabaseFormat.SupportsOverrideUrl)
|
||||
if (App.Kp2a.CurrentDb.DatabaseFormat.SupportsOverrideUrl)
|
||||
{
|
||||
PopulateText(Resource.Id.entry_override_url, State.Entry.OverrideUrl);
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.entry_override_url_container).Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
if (App.Kp2a.GetDb().DatabaseFormat.SupportsTags)
|
||||
if (App.Kp2a.CurrentDb.DatabaseFormat.SupportsTags)
|
||||
{
|
||||
PopulateText(Resource.Id.entry_tags, StrUtil.TagsToString(State.Entry.Tags, true));
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ namespace keepass2android
|
||||
public override void Run()
|
||||
{
|
||||
StatusLogger.UpdateMessage(UiStringKey.exporting_database);
|
||||
var pd = _app.GetDb().KpDatabase;
|
||||
var pd = _app.CurrentDb.KpDatabase;
|
||||
PwExportInfo pwInfo = new PwExportInfo(pd.RootGroup, pd, true);
|
||||
|
||||
try
|
||||
@@ -117,7 +117,7 @@ namespace keepass2android
|
||||
{
|
||||
((IOfflineSwitchable) fileStorage).IsOffline = false;
|
||||
}
|
||||
using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetDb().KpDatabase.UseFileTransactions))
|
||||
using (var writeTransaction = fileStorage.OpenWriteTransaction(_targetIoc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
|
||||
{
|
||||
Stream sOut = writeTransaction.OpenFile();
|
||||
_fileFormat.Export(pwInfo, sOut, new NullStatusLogger());
|
||||
|
@@ -64,7 +64,7 @@ namespace keepass2android
|
||||
SetContentView(Resource.Layout.fingerprint_setup);
|
||||
|
||||
Enum.TryParse(
|
||||
PreferenceManager.GetDefaultSharedPreferences(this).GetString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, ""),
|
||||
PreferenceManager.GetDefaultSharedPreferences(this).GetString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, ""),
|
||||
out _unlockMode);
|
||||
|
||||
_fpIcon = FindViewById<ImageView>(Resource.Id.fingerprint_icon);
|
||||
@@ -174,7 +174,7 @@ namespace keepass2android
|
||||
|
||||
string CurrentPreferenceKey
|
||||
{
|
||||
get { return App.Kp2a.GetDb().CurrentFingerprintPrefKey; }
|
||||
get { return App.Kp2a.CurrentDb.CurrentFingerprintPrefKey; }
|
||||
}
|
||||
|
||||
private void StoreUnlockMode()
|
||||
@@ -188,13 +188,13 @@ namespace keepass2android
|
||||
{
|
||||
if (_unlockMode == FingerprintUnlockMode.FullUnlock)
|
||||
{
|
||||
var userKey = App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey<KcpPassword>();
|
||||
var userKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey.GetUserKey<KcpPassword>();
|
||||
_enc.StoreEncrypted(userKey != null ? userKey.Password.ReadString() : "", CurrentPreferenceKey, edit);
|
||||
}
|
||||
else
|
||||
_enc.StoreEncrypted("QuickUnlock" /*some dummy data*/, CurrentPreferenceKey, edit);
|
||||
}
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, _unlockMode.ToString());
|
||||
edit.PutString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, _unlockMode.ToString());
|
||||
edit.Commit();
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace keepass2android
|
||||
UpdateKeyboardCheckboxVisibility();
|
||||
|
||||
ISharedPreferencesEditor edit = PreferenceManager.GetDefaultSharedPreferences(this).Edit();
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, _unlockMode.ToString());
|
||||
edit.PutString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, _unlockMode.ToString());
|
||||
edit.Commit();
|
||||
return;
|
||||
}
|
||||
|
@@ -69,15 +69,6 @@ namespace keepass2android
|
||||
|
||||
public static void Launch (Activity act, PwGroup g, AppTask appTask)
|
||||
{
|
||||
// Need to use PwDatabase since group may be null
|
||||
PwDatabase db = App.Kp2a.GetDb().KpDatabase;
|
||||
|
||||
if (db == null) {
|
||||
// Reached if db is null
|
||||
Log.Debug (Tag, "Tried to launch with null db");
|
||||
return;
|
||||
}
|
||||
|
||||
Intent i = new Intent(act, typeof(GroupActivity));
|
||||
|
||||
if ( g != null ) {
|
||||
@@ -105,10 +96,15 @@ namespace keepass2android
|
||||
|
||||
protected override bool AddEntryEnabled
|
||||
{
|
||||
get { return App.Kp2a.GetDb().CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.GetDb().DatabaseFormat.CanHaveEntriesInRootGroup); }
|
||||
get { return App.Kp2a.CurrentDb.CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.CurrentDb.DatabaseFormat.CanHaveEntriesInRootGroup); }
|
||||
}
|
||||
|
||||
private class TemplateListAdapter : ArrayAdapter<PwEntry>
|
||||
protected override bool AddGroupEnabled
|
||||
{
|
||||
get { return App.Kp2a.CurrentDb.CanWrite; }
|
||||
}
|
||||
|
||||
private class TemplateListAdapter : ArrayAdapter<PwEntry>
|
||||
{
|
||||
public TemplateListAdapter(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
|
||||
{
|
||||
@@ -149,8 +145,7 @@ namespace keepass2android
|
||||
int size = (int)(Util.convertDpToPixel(Util.convertDpToPixel(20, Context), Context));
|
||||
var bmp =
|
||||
Bitmap.CreateScaledBitmap(
|
||||
Util.DrawableToBitmap(App.Kp2a.GetDb()
|
||||
.DrawableFactory.GetIconDrawable(Context, App.Kp2a.GetDb().KpDatabase, templateEntry.IconId, PwUuid.Zero, false)),
|
||||
Util.DrawableToBitmap(App.Kp2a.CurrentDb .DrawableFactory.GetIconDrawable(Context, App.Kp2a.CurrentDb.KpDatabase, templateEntry.IconId, PwUuid.Zero, false)),
|
||||
size, size,
|
||||
true);
|
||||
|
||||
@@ -193,7 +188,7 @@ namespace keepass2android
|
||||
|
||||
PwUuid id = RetrieveGroupId (intent);
|
||||
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
if (id == null) {
|
||||
Group = db.Root;
|
||||
} else {
|
||||
@@ -221,8 +216,8 @@ namespace keepass2android
|
||||
View addEntry = FindViewById (Resource.Id.fabAddNewEntry);
|
||||
addEntry.Click += (sender, e) =>
|
||||
{
|
||||
if (App.Kp2a.GetDb().DatabaseFormat.SupportsTemplates &&
|
||||
!AddTemplateEntries.ContainsAllTemplates(App.Kp2a) &&
|
||||
if (App.Kp2a.CurrentDb.DatabaseFormat.SupportsTemplates &&
|
||||
!AddTemplateEntries.ContainsAllTemplates(App.Kp2a.CurrentDb) &&
|
||||
PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(Askaddtemplates, true))
|
||||
{
|
||||
App.Kp2a.AskYesNoCancel(UiStringKey.AskAddTemplatesTitle, UiStringKey.AskAddTemplatesMessage,UiStringKey.yes, UiStringKey.no,
|
||||
@@ -256,14 +251,14 @@ namespace keepass2android
|
||||
FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group);
|
||||
Log.Warn(Tag, "Finished creating group");
|
||||
|
||||
var ioc = App.Kp2a.GetDb().Ioc;
|
||||
var ioc = App.Kp2a.CurrentDb.Ioc;
|
||||
OptionalOut<UiStringKey> reason = new OptionalOut<UiStringKey>();
|
||||
|
||||
if (App.Kp2a.GetFileStorage(ioc).IsReadOnly(ioc, reason))
|
||||
{
|
||||
bool hasShownReadOnlyReason =
|
||||
PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(App.Kp2a.GetDb().IocAsHexString() + "_readonlyreason", false);
|
||||
.GetBoolean(App.Kp2a.CurrentDb.IocAsHexString() + "_readonlyreason", false);
|
||||
if (!hasShownReadOnlyReason)
|
||||
{
|
||||
var b = new AlertDialog.Builder(this);
|
||||
@@ -273,7 +268,7 @@ namespace keepass2android
|
||||
(sender, args) =>
|
||||
{
|
||||
PreferenceManager.GetDefaultSharedPreferences(this).
|
||||
Edit().PutBoolean(App.Kp2a.GetDb().IocAsHexString() + "_readonlyreason", true).Commit();
|
||||
Edit().PutBoolean(App.Kp2a.CurrentDb.IocAsHexString() + "_readonlyreason", true).Commit();
|
||||
});
|
||||
b.Show();
|
||||
}
|
||||
@@ -287,11 +282,11 @@ namespace keepass2android
|
||||
defaultTemplate.IconId = PwIcon.Key;
|
||||
defaultTemplate.Strings.Set(PwDefs.TitleField, new ProtectedString(false, GetString(Resource.String.DefaultTemplate)));
|
||||
List<PwEntry> templates = new List<PwEntry>() {defaultTemplate};
|
||||
if ((!PwUuid.Zero.Equals(App.Kp2a.GetDb().KpDatabase.EntryTemplatesGroup))
|
||||
&& (App.Kp2a.GetDb().KpDatabase.RootGroup.FindGroup(App.Kp2a.GetDb().KpDatabase.EntryTemplatesGroup, true) != null))
|
||||
if ((!PwUuid.Zero.Equals(App.Kp2a.CurrentDb.KpDatabase.EntryTemplatesGroup))
|
||||
&& (App.Kp2a.CurrentDb.KpDatabase.RootGroup.FindGroup(App.Kp2a.CurrentDb.KpDatabase.EntryTemplatesGroup, true) != null))
|
||||
{
|
||||
templates.AddRange(
|
||||
App.Kp2a.GetDb().Groups[App.Kp2a.GetDb().KpDatabase.EntryTemplatesGroup].Entries.OrderBy(
|
||||
App.Kp2a.CurrentDb.Groups[App.Kp2a.CurrentDb.KpDatabase.EntryTemplatesGroup].Entries.OrderBy(
|
||||
entr => entr.Strings.ReadSafe(PwDefs.TitleField)));
|
||||
}
|
||||
if (templates.Count > 1)
|
||||
@@ -316,7 +311,12 @@ namespace keepass2android
|
||||
cv.OnCreateMenu(menu, menuInfo);
|
||||
}
|
||||
|
||||
public override void OnBackPressed()
|
||||
public override bool EntriesBelongToCurrentDatabaseOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override void OnBackPressed()
|
||||
{
|
||||
base.OnBackPressed();
|
||||
//if ((Group != null) && (Group.ParentGroup != null))
|
||||
|
@@ -95,11 +95,11 @@ namespace keepass2android
|
||||
|
||||
protected virtual bool AddGroupEnabled
|
||||
{
|
||||
get { return App.Kp2a.GetDb().CanWrite; }
|
||||
get { return false; }
|
||||
}
|
||||
protected virtual bool AddEntryEnabled
|
||||
{
|
||||
get { return App.Kp2a.GetDb().CanWrite; }
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public void SetNormalButtonVisibility(bool showAddGroup, bool showAddEntry)
|
||||
@@ -186,7 +186,7 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
PwUuid groupUuid = new PwUuid(MemUtil.HexStringToByteArray(strGroupUuid));
|
||||
task = new EditGroup(this, App.Kp2a, groupName, (PwIcon)groupIconId, groupCustomIconId, App.Kp2a.GetDb().Groups[groupUuid],
|
||||
task = new EditGroup(this, App.Kp2a, groupName, (PwIcon)groupIconId, groupCustomIconId, App.Kp2a.FindGroup(groupUuid),
|
||||
new RefreshTask(handler, this));
|
||||
}
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, act, task);
|
||||
@@ -258,7 +258,7 @@ namespace keepass2android
|
||||
{
|
||||
|
||||
FingerprintUnlockMode um;
|
||||
Enum.TryParse(_prefs.GetString(Database.GetFingerprintModePrefKey(App.Kp2a.GetDb().Ioc), ""), out um);
|
||||
Enum.TryParse(_prefs.GetString(Database.GetFingerprintModePrefKey(App.Kp2a.CurrentDb.Ioc), ""), out um);
|
||||
bool isFingerprintEnabled = (um == FingerprintUnlockMode.FullUnlock);
|
||||
|
||||
string masterKeyKey = "MasterKey" + isFingerprintEnabled;
|
||||
@@ -267,11 +267,11 @@ namespace keepass2android
|
||||
|
||||
List<string> applicableInfoTextKeys = new List<string> { masterKeyKey };
|
||||
|
||||
if (App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc).UserShouldBackup)
|
||||
if (App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc).UserShouldBackup)
|
||||
{
|
||||
applicableInfoTextKeys.Add(backupKey);
|
||||
}
|
||||
if (App.Kp2a.GetDb().Entries.Count > 15)
|
||||
if (App.Kp2a.CurrentDb.Entries.Count > 15)
|
||||
{
|
||||
applicableInfoTextKeys.Add(emergencyKey);
|
||||
}
|
||||
@@ -378,10 +378,9 @@ namespace keepass2android
|
||||
|
||||
public void RefreshIfDirty()
|
||||
{
|
||||
Database db = App.Kp2a.GetDb();
|
||||
if (db.Dirty.Contains(Group))
|
||||
if (App.Kp2a.DirtyGroups.Contains(Group))
|
||||
{
|
||||
db.Dirty.Remove(Group);
|
||||
App.Kp2a.DirtyGroups.Remove(Group);
|
||||
ListAdapter.NotifyDataSetChanged();
|
||||
|
||||
}
|
||||
@@ -407,7 +406,7 @@ namespace keepass2android
|
||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
|
||||
// Likely the app has been killed exit the activity
|
||||
if (App.Kp2a.GetDb() == null)
|
||||
if (App.Kp2a.CurrentDb== null)
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
@@ -458,7 +457,7 @@ namespace keepass2android
|
||||
{
|
||||
FindViewById(Resource.Id.hide_fingerprint_info).Click += (sender, args) =>
|
||||
{
|
||||
_prefs.Edit().PutBoolean(fingerprintinfohidden_prefskey + App.Kp2a.GetDb().CurrentFingerprintPrefKey, true).Commit();
|
||||
_prefs.Edit().PutBoolean(fingerprintinfohidden_prefskey + App.Kp2a.CurrentDb.CurrentFingerprintPrefKey, true).Commit();
|
||||
UpdateFingerprintInfo();
|
||||
};
|
||||
}
|
||||
@@ -627,7 +626,7 @@ namespace keepass2android
|
||||
{
|
||||
bool canShowFingerprintInfo = false;
|
||||
|
||||
bool disabledForDatabase = _prefs.GetBoolean(fingerprintinfohidden_prefskey + App.Kp2a.GetDb().CurrentFingerprintPrefKey, false);
|
||||
bool disabledForDatabase = _prefs.GetBoolean(fingerprintinfohidden_prefskey + App.Kp2a.CurrentDb.CurrentFingerprintPrefKey, false);
|
||||
bool disabledForAll = _prefs.GetBoolean(fingerprintinfohidden_prefskey, false);
|
||||
if (!disabledForAll && !disabledForDatabase)
|
||||
{
|
||||
@@ -636,7 +635,7 @@ namespace keepass2android
|
||||
if (fpModule.FingerprintManager != null && fpModule.FingerprintManager.IsHardwareDetected)
|
||||
{
|
||||
FingerprintUnlockMode um;
|
||||
Enum.TryParse(_prefs.GetString(Database.GetFingerprintModePrefKey(App.Kp2a.GetDb().Ioc), ""), out um);
|
||||
Enum.TryParse(_prefs.GetString(Database.GetFingerprintModePrefKey(App.Kp2a.CurrentDb.Ioc), ""), out um);
|
||||
canShowFingerprintInfo = um == FingerprintUnlockMode.Disabled;
|
||||
}
|
||||
}
|
||||
@@ -667,8 +666,7 @@ namespace keepass2android
|
||||
private void InsertElements()
|
||||
{
|
||||
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||
IEnumerable<IStructureItem> elementsToMove =
|
||||
moveElementsTask.Uuids.Select(uuid => App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(uuid, true, null));
|
||||
IEnumerable<IStructureItem> elementsToMove = moveElementsTask.Uuids.Select(uuid => App.Kp2a.FindStructureItem(uuid));
|
||||
|
||||
|
||||
|
||||
@@ -690,7 +688,7 @@ namespace keepass2android
|
||||
{
|
||||
String name = Group.Name;
|
||||
String titleText;
|
||||
bool clickable = (Group != null) && (Group.IsVirtual == false) && (Group.ParentGroup != null);
|
||||
bool clickable = (Group != null) && (Group.IsVirtual == false) && ((Group.ParentGroup != null) || App.Kp2a.OpenDatabases.Count() > 1);
|
||||
if (!String.IsNullOrEmpty(name))
|
||||
{
|
||||
titleText = name;
|
||||
@@ -715,9 +713,7 @@ namespace keepass2android
|
||||
{
|
||||
if (Group != null)
|
||||
{
|
||||
Drawable drawable = App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(this, App.Kp2a.GetDb().KpDatabase, Group.IconId, Group.CustomIconUuid, true);
|
||||
SupportActionBar.SetDisplayShowHomeEnabled(true);
|
||||
//SupportActionBar.SetIcon(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +736,8 @@ namespace keepass2android
|
||||
var cursor = _suggestionsAdapter.Cursor;
|
||||
cursor.MoveToPosition(position);
|
||||
string entryIdAsHexString = cursor.GetString(cursor.GetColumnIndexOrThrow(SearchManager.SuggestColumnIntentDataId));
|
||||
EntryActivity.Launch(_activity, App.Kp2a.GetDb().Entries[new PwUuid(MemUtil.HexStringToByteArray(entryIdAsHexString))], -1, _activity.AppTask);
|
||||
var entryId = new PwUuid(MemUtil.HexStringToByteArray(entryIdAsHexString));
|
||||
EntryActivity.Launch(_activity, App.Kp2a.FindDatabaseForEntryId(entryId).Entries[entryId], -1, _activity.AppTask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -830,35 +827,34 @@ namespace keepass2android
|
||||
{
|
||||
if (_syncItem != null)
|
||||
{
|
||||
if (App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||
if (((App.Kp2a.OpenDatabases.Count() == 1) || (EntriesBelongToCurrentDatabaseOnly))
|
||||
&& App.Kp2a.CurrentDb.Ioc.IsLocalFile())
|
||||
_syncItem.SetVisible(false);
|
||||
else
|
||||
_syncItem.SetVisible(!App.Kp2a.OfflineMode);
|
||||
}
|
||||
|
||||
if (App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc) is IOfflineSwitchable)
|
||||
if (((App.Kp2a.OpenDatabases.Count() == 1) || (EntriesBelongToCurrentDatabaseOnly))
|
||||
&& (App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc) is IOfflineSwitchable))
|
||||
{
|
||||
if (_offlineItem != null)
|
||||
_offlineItem.SetVisible(App.Kp2a.OfflineMode == false);
|
||||
if (_onlineItem != null)
|
||||
_onlineItem.SetVisible(App.Kp2a.OfflineMode);
|
||||
_offlineItem?.SetVisible(App.Kp2a.OfflineMode == false);
|
||||
_onlineItem?.SetVisible(App.Kp2a.OfflineMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_offlineItem != null)
|
||||
_offlineItem.SetVisible(false);
|
||||
if (_onlineItem != null)
|
||||
_onlineItem.SetVisible(false);
|
||||
|
||||
_offlineItem?.SetVisible(false);
|
||||
_onlineItem?.SetVisible(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(new Exception("Cannot UpdateOfflineModeMenu " + (App.Kp2a == null) + " " + ((App.Kp2a == null) || (App.Kp2a.GetDb() == null)) + " " + (((App.Kp2a == null) || (App.Kp2a.GetDb() == null) || (App.Kp2a.GetDb().Ioc == null)) + " " + (_syncItem != null) + " " + (_offlineItem != null) + " " + (_onlineItem != null))));
|
||||
Kp2aLog.LogUnexpectedError(new Exception("Cannot UpdateOfflineModeMenu " + (App.Kp2a == null) + " " + ((App.Kp2a == null) || (App.Kp2a.CurrentDb== null)) + " " + (((App.Kp2a == null) || (App.Kp2a.CurrentDb== null) || (App.Kp2a.CurrentDb.Ioc == null)) + " " + (_syncItem != null) + " " + (_offlineItem != null) + " " + (_onlineItem != null))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract bool EntriesBelongToCurrentDatabaseOnly { get; }
|
||||
|
||||
|
||||
public override bool OnPrepareOptionsMenu(IMenu menu)
|
||||
{
|
||||
@@ -880,7 +876,7 @@ namespace keepass2android
|
||||
case Resource.Id.menu_donate:
|
||||
return Util.GotoDonateUrl(this);
|
||||
case Resource.Id.menu_lock:
|
||||
App.Kp2a.LockDatabase();
|
||||
App.Kp2a.Lock();
|
||||
return true;
|
||||
|
||||
case Resource.Id.menu_search:
|
||||
@@ -906,8 +902,10 @@ namespace keepass2android
|
||||
UpdateOfflineModeMenu();
|
||||
Synchronize();
|
||||
return true;
|
||||
|
||||
|
||||
case Resource.Id.menu_open_other_db:
|
||||
AppTask.SetActivityResult(this, KeePass.ExitLoadAnotherDb);
|
||||
Finish();
|
||||
return true;
|
||||
case Resource.Id.menu_sort:
|
||||
ChangeSort();
|
||||
return true;
|
||||
@@ -960,7 +958,7 @@ namespace keepass2android
|
||||
|
||||
private void Synchronize()
|
||||
{
|
||||
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc);
|
||||
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc);
|
||||
RunnableOnFinish task;
|
||||
OnFinish onFinish = new ActionOnFinish(this, (success, message, activity) =>
|
||||
{
|
||||
@@ -971,9 +969,9 @@ namespace keepass2android
|
||||
BaseAdapter adapter = (BaseAdapter)((GroupBaseActivity)activity)?.ListAdapter;
|
||||
adapter?.NotifyDataSetChanged();
|
||||
|
||||
if (App.Kp2a.GetDb().OtpAuxFileIoc != null)
|
||||
if (App.Kp2a.CurrentDb.OtpAuxFileIoc != null)
|
||||
{
|
||||
var task2 = new SyncOtpAuxFile(this, App.Kp2a.GetDb().OtpAuxFileIoc);
|
||||
var task2 = new SyncOtpAuxFile(this, App.Kp2a.CurrentDb.OtpAuxFileIoc);
|
||||
new ProgressTask(App.Kp2a, activity, task2).Run(true);
|
||||
}
|
||||
});
|
||||
@@ -1022,10 +1020,10 @@ namespace keepass2android
|
||||
ActivityCompat.InvalidateOptionsMenu(this);
|
||||
|
||||
// Mark all groups as dirty now to refresh them on load
|
||||
Database db = App.Kp2a.GetDb();
|
||||
db.MarkAllGroupsAsDirty();
|
||||
|
||||
App.Kp2a.MarkAllGroupsAsDirty();
|
||||
// We'll manually refresh this group so we can remove it
|
||||
db.Dirty.Remove(Group);
|
||||
App.Kp2a.DirtyGroups.Remove(Group);
|
||||
|
||||
// Tell the adapter to refresh it's list
|
||||
|
||||
@@ -1082,7 +1080,7 @@ namespace keepass2android
|
||||
Toast.MakeText(ActiveActivity, "Unrecoverable error: " + Message, ToastLength.Long).Show();
|
||||
});
|
||||
|
||||
App.Kp2a.LockDatabase(false);
|
||||
App.Kp2a.Lock(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1133,9 +1131,9 @@ namespace keepass2android
|
||||
MoveElementsTask moveElementsTask = (MoveElementsTask)AppTask;
|
||||
foreach (var uuid in moveElementsTask.Uuids)
|
||||
{
|
||||
IStructureItem elementToMove = App.Kp2a.GetDb().KpDatabase.RootGroup.FindObject(uuid, true, null);
|
||||
IStructureItem elementToMove = App.Kp2a.FindStructureItem(uuid);
|
||||
if (elementToMove.ParentGroup != Group)
|
||||
App.Kp2a.GetDb().Dirty.Add(elementToMove.ParentGroup);
|
||||
App.Kp2a.DirtyGroups.Add(elementToMove.ParentGroup);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -1167,7 +1165,7 @@ namespace keepass2android
|
||||
base.OnActivityCreated(savedInstanceState);
|
||||
|
||||
ListView.SetMultiChoiceModeListener(this);
|
||||
if (App.Kp2a.GetDb().CanWrite)
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
ListView.ChoiceMode = ChoiceMode.MultipleModal;
|
||||
|
||||
@@ -1221,13 +1219,10 @@ namespace keepass2android
|
||||
{
|
||||
|
||||
case Resource.Id.menu_delete:
|
||||
|
||||
DeleteMultipleItems task = new DeleteMultipleItems((GroupBaseActivity)Activity, App.Kp2a.GetDb(), checkedItems,
|
||||
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)), App.Kp2a);
|
||||
task.Start();
|
||||
DeleteMultipleItems((GroupBaseActivity)Activity, checkedItems, new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)), App.Kp2a);
|
||||
break;
|
||||
case Resource.Id.menu_move:
|
||||
var navMove = new NavigateToFolderAndLaunchMoveElementTask(checkedItems.First().ParentGroup, checkedItems.Select(i => i.Uuid).ToList(), ((GroupBaseActivity)Activity).IsSearchResult);
|
||||
var navMove = new NavigateToFolderAndLaunchMoveElementTask(App.Kp2a.CurrentDb, checkedItems.First().ParentGroup, checkedItems.Select(i => i.Uuid).ToList(), ((GroupBaseActivity)Activity).IsSearchResult);
|
||||
((GroupBaseActivity)Activity).StartTask(navMove);
|
||||
break;
|
||||
case Resource.Id.menu_copy:
|
||||
@@ -1240,7 +1235,7 @@ namespace keepass2android
|
||||
break;
|
||||
|
||||
case Resource.Id.menu_navigate:
|
||||
NavigateToFolder navNavigate = new NavigateToFolder(checkedItems.First().ParentGroup, true);
|
||||
NavigateToFolder navNavigate = new NavigateToFolder(App.Kp2a.CurrentDb, checkedItems.First().ParentGroup, true);
|
||||
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
||||
break;
|
||||
case Resource.Id.menu_edit:
|
||||
@@ -1378,6 +1373,66 @@ namespace keepass2android
|
||||
{
|
||||
return IsOnlyOneItemChecked() && !IsOnlyOneGroupChecked();
|
||||
}
|
||||
|
||||
|
||||
public void DeleteMultipleItems(GroupBaseActivity activity, List<IStructureItem> checkedItems, OnFinish onFinish, Kp2aApp app)
|
||||
{
|
||||
if (checkedItems.Any() == false)
|
||||
return;
|
||||
//sort checkedItems by database
|
||||
List<KeyValuePair<Database, List<IStructureItem>>> itemsForDatabases =
|
||||
new List<KeyValuePair<Database, List<IStructureItem>>>();
|
||||
foreach (var item in checkedItems)
|
||||
{
|
||||
var db = app.FindDatabaseForEntryId(item.Uuid) ?? app.FindDatabaseForGroupId(item.Uuid);
|
||||
if (db != null)
|
||||
{
|
||||
bool foundDatabase = false;
|
||||
foreach (var listEntry in itemsForDatabases)
|
||||
{
|
||||
if (listEntry.Key == db)
|
||||
{
|
||||
foundDatabase = true;
|
||||
listEntry.Value.Add(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundDatabase)
|
||||
{
|
||||
itemsForDatabases.Add(new KeyValuePair<Database, List<IStructureItem>>(db, new List<IStructureItem> { item }));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int dbIndex = 0;
|
||||
Action<bool, string, Activity> action = null;
|
||||
action = (success, message, activeActivity) =>
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
dbIndex++;
|
||||
if (dbIndex == itemsForDatabases.Count)
|
||||
{
|
||||
onFinish.SetResult(true);
|
||||
onFinish.Run();
|
||||
return;
|
||||
}
|
||||
new DeleteMultipleItemsFromOneDatabase(activity, itemsForDatabases[dbIndex].Key,
|
||||
itemsForDatabases[dbIndex].Value, new ActionOnFinish(activeActivity, (b, s, activity1) => action(b, s, activity1)), app)
|
||||
.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
onFinish.SetResult(false, message, null);
|
||||
}
|
||||
};
|
||||
|
||||
new DeleteMultipleItemsFromOneDatabase(activity, itemsForDatabases[dbIndex].Key,
|
||||
itemsForDatabases[dbIndex].Value, new ActionOnFinish(activity, (b, s, activity1) => action(b, s, activity1)), app)
|
||||
.Start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -90,7 +90,7 @@ namespace keepass2android
|
||||
};
|
||||
_selectedIconId = (int) PwIcon.FolderOpen;
|
||||
|
||||
iconButton.SetImageDrawable(App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(this, App.Kp2a.GetDb().KpDatabase, (PwIcon)_selectedIconId, null, true));
|
||||
iconButton.SetImageDrawable(App.Kp2a.CurrentDb.DrawableFactory.GetIconDrawable(this, App.Kp2a.CurrentDb.KpDatabase, (PwIcon)_selectedIconId, null, true));
|
||||
|
||||
Button okButton = (Button)FindViewById (Resource.Id.ok);
|
||||
okButton.Click += (sender, e) => {
|
||||
@@ -118,12 +118,12 @@ namespace keepass2android
|
||||
if (Intent.HasExtra(KeyGroupUuid))
|
||||
{
|
||||
string groupUuid = Intent.Extras.GetString(KeyGroupUuid);
|
||||
_groupToEdit = App.Kp2a.GetDb().Groups[new PwUuid(MemUtil.HexStringToByteArray(groupUuid))];
|
||||
_groupToEdit = App.Kp2a.CurrentDb.Groups[new PwUuid(MemUtil.HexStringToByteArray(groupUuid))];
|
||||
_selectedIconId = (int) _groupToEdit.IconId;
|
||||
_selectedCustomIconId = _groupToEdit.CustomIconUuid;
|
||||
TextView nameField = (TextView)FindViewById(Resource.Id.group_name);
|
||||
nameField.Text = _groupToEdit.Name;
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iconButton, this, App.Kp2a.GetDb().KpDatabase, _groupToEdit.IconId, _groupToEdit.CustomIconUuid, false);
|
||||
App.Kp2a.CurrentDb.DrawableFactory.AssignDrawableTo(iconButton, this, App.Kp2a.CurrentDb.KpDatabase, _groupToEdit.IconId, _groupToEdit.CustomIconUuid, false);
|
||||
SetTitle(Resource.String.edit_group_title);
|
||||
}
|
||||
else
|
||||
@@ -156,7 +156,7 @@ namespace keepass2android
|
||||
_selectedCustomIconId = PwUuid.Zero;
|
||||
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(currIconButton, this, App.Kp2a.GetDb().KpDatabase, (PwIcon) _selectedIconId, _selectedCustomIconId, false);
|
||||
App.Kp2a.CurrentDb.DrawableFactory.AssignDrawableTo(currIconButton, this, App.Kp2a.CurrentDb.KpDatabase, (PwIcon) _selectedIconId, _selectedCustomIconId, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ namespace keepass2android
|
||||
SetContentView(Resource.Layout.icon_picker);
|
||||
|
||||
GridView currIconGridView = (GridView)FindViewById(Resource.Id.IconGridView);
|
||||
currIconGridView.Adapter = new ImageAdapter(this, App.Kp2a.GetDb().KpDatabase);
|
||||
currIconGridView.Adapter = new ImageAdapter(this, App.Kp2a.CurrentDb.KpDatabase);
|
||||
|
||||
currIconGridView.ItemClick += (sender, e) =>
|
||||
{
|
||||
@@ -134,7 +134,7 @@ namespace keepass2android
|
||||
bitmap.Compress(Bitmap.CompressFormat.Png, 90, ms);
|
||||
PwCustomIcon pwci = new PwCustomIcon(new PwUuid(true), ms.ToArray());
|
||||
|
||||
App.Kp2a.GetDb().KpDatabase.CustomIcons.Add(pwci);
|
||||
App.Kp2a.CurrentDb.KpDatabase.CustomIcons.Add(pwci);
|
||||
|
||||
}
|
||||
var gridView = ((GridView)FindViewById(Resource.Id.IconGridView));
|
||||
@@ -198,8 +198,7 @@ namespace keepass2android
|
||||
if (position < (int)PwIcon.Count)
|
||||
{
|
||||
tv.Text = "" + position;
|
||||
var drawable = App.Kp2a.GetDb()
|
||||
.DrawableFactory.GetIconDrawable(_act, App.Kp2a.GetDb().KpDatabase, (KeePassLib.PwIcon) position, null, false);
|
||||
var drawable = App.Kp2a.CurrentDb .DrawableFactory.GetIconDrawable(_act, App.Kp2a.CurrentDb.KpDatabase, (KeePassLib.PwIcon) position, null, false);
|
||||
drawable = new BitmapDrawable(Util.DrawableToBitmap(drawable));
|
||||
iv.SetImageDrawable(drawable);
|
||||
//App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, _act, App.Kp2a.GetDb().KpDatabase, (KeePassLib.PwIcon) position, null, false);
|
||||
|
@@ -317,7 +317,7 @@ namespace keepass2android
|
||||
SetContentView(Resource.Layout.ImageViewActivity);
|
||||
var uuid = new PwUuid(MemUtil.HexStringToByteArray(Intent.GetStringExtra("EntryId")));
|
||||
string key = Intent.GetStringExtra("EntryKey");
|
||||
var binary = App.Kp2a.GetDb().Entries[uuid].Binaries.Get(key);
|
||||
var binary = App.Kp2a.FindDatabaseForEntryId(uuid).Entries[uuid].Binaries.Get(key);
|
||||
SupportActionBar.Title = key;
|
||||
byte[] pbdata = binary.ReadData();
|
||||
|
||||
|
@@ -38,8 +38,8 @@ using String = System.String;
|
||||
* Keepass2Android comprises quite a number of different activities and entry points: The app can be started
|
||||
* using the launcher icon (-> Activity "Keepass"), or by sending a URL (-> FileSelect), opening a .kdb(x)-file (->Password),
|
||||
* swiping a YubikeyNEO (NfcOtpActivity).
|
||||
* While the database is closed, there is only one activity on the stack: Keepass -> FileSelect <-> Password.
|
||||
* After opening an database (in Password), Password is always the root of the stack (exception: after creating a database,
|
||||
* There is either only the KeePass activity on stack (no db loaded then) or the first activity
|
||||
* After opening a database (in Password), Password is always the root of the stack (exception: after creating a database,
|
||||
* FileSelect is the root without Password being open).
|
||||
* Another exception: QueryCredentialsActivity is root of the stack if an external app is querying credentials.
|
||||
* QueryCredentialsActivity checks the plugin access permissions, then launches FileSelectActivity (which starts
|
||||
@@ -86,8 +86,10 @@ namespace keepass2android
|
||||
public const Result ExitClose = Result.FirstUser + 7;
|
||||
public const Result ExitFileStorageSelectionOk = Result.FirstUser + 8;
|
||||
public const Result ResultOkPasswordGenerator = Result.FirstUser + 9;
|
||||
public const Result ExitLoadAnotherDb = Result.FirstUser + 10;
|
||||
|
||||
public const string TagsKey = "@tags";
|
||||
|
||||
public const string TagsKey = "@tags";
|
||||
public const string OverrideUrlKey = "@override";
|
||||
public const string ExpDateKey = "@exp_date";
|
||||
|
||||
|
@@ -38,7 +38,7 @@ namespace keepass2android
|
||||
return res;
|
||||
}
|
||||
|
||||
private const string EtmTemplateUuid = "_etm_template_uuid";
|
||||
public const string EtmTemplateUuid = "_etm_template_uuid";
|
||||
private const string EtmTitle = "_etm_title_";
|
||||
private readonly Database _db;
|
||||
private readonly PwEntry _entry;
|
||||
|
@@ -51,7 +51,7 @@ namespace keepass2android
|
||||
{
|
||||
base.OnResume();
|
||||
Kp2aLog.Log(ClassName+".OnResume");
|
||||
if (App.Kp2a.GetDb() == null)
|
||||
if (App.Kp2a.CurrentDb== null)
|
||||
{
|
||||
Kp2aLog.Log(" DB null");
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
_ioc = App.Kp2a.GetDb().Ioc;
|
||||
_ioc = App.Kp2a.CurrentDb.Ioc;
|
||||
|
||||
if (Intent.GetBooleanExtra(NoLockCheck, false))
|
||||
return;
|
||||
@@ -106,10 +106,13 @@ namespace keepass2android
|
||||
if (Intent.GetBooleanExtra(NoLockCheck, false))
|
||||
return;
|
||||
|
||||
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||
return;
|
||||
if (TimeoutHelper.CheckDbChanged(this, _ioc))
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
//todo: it seems like OnResume can be called after dismissing a dialog, e.g. the Delete-permanently-Dialog.
|
||||
//todo: it seems like OnResume can be called after dismissing a dialog, e.g. the Delete-permanently-Dialog.
|
||||
//in this case the following check might run in parallel with the check performed during the SaveDb check (triggered after the
|
||||
//aforementioned dialog is closed) which can cause odd behavior. However, this is a rare case and hard to resolve so this is currently
|
||||
//accepted. (If the user clicks cancel on the reload-dialog, everything will work.)
|
||||
|
@@ -51,7 +51,7 @@ namespace keepass2android
|
||||
Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
|
||||
}
|
||||
|
||||
_ioc = App.Kp2a.GetDb().Ioc;
|
||||
_ioc = App.Kp2a.CurrentDb.Ioc;
|
||||
|
||||
_intentReceiver = new LockCloseListActivityBroadcastReceiver(this);
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -73,10 +73,13 @@ namespace keepass2android
|
||||
base.OnResume();
|
||||
_design.ReapplyTheme();
|
||||
|
||||
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||
return;
|
||||
if (TimeoutHelper.CheckDbChanged(this, _ioc))
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
//todo: see LockCloseActivity.OnResume
|
||||
//todo: see LockCloseActivity.OnResume
|
||||
App.Kp2a.CheckForOpenFileChanged(this);
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ namespace keepass2android
|
||||
{
|
||||
base.OnStart();
|
||||
|
||||
var xcKey = App.Kp2a.GetDb()?.KpDatabase.MasterKey.GetUserKey<ChallengeXCKey>();
|
||||
var xcKey = App.Kp2a.CurrentDb?.KpDatabase.MasterKey.GetUserKey<ChallengeXCKey>();
|
||||
if (xcKey != null)
|
||||
{
|
||||
xcKey.Activity = this;
|
||||
@@ -58,7 +58,7 @@ namespace keepass2android
|
||||
protected override void OnStop()
|
||||
{
|
||||
base.OnStop();
|
||||
var xcKey = App.Kp2a.GetDb()?.KpDatabase.MasterKey.GetUserKey<ChallengeXCKey>();
|
||||
var xcKey = App.Kp2a.CurrentDb?.KpDatabase.MasterKey.GetUserKey<ChallengeXCKey>();
|
||||
if (xcKey != null)
|
||||
{
|
||||
//don't store a pointer to this activity in the static database object to avoid memory leak
|
||||
|
@@ -32,7 +32,7 @@ namespace keepass2android
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
_ioc = App.Kp2a.GetDb().Ioc;
|
||||
_ioc = App.Kp2a.CurrentDb.Ioc;
|
||||
|
||||
|
||||
_intentReceiver = new LockingClosePreferenceActivityBroadcastReceiver(this);
|
||||
@@ -44,7 +44,11 @@ namespace keepass2android
|
||||
protected override void OnResume() {
|
||||
base.OnResume();
|
||||
|
||||
TimeoutHelper.CheckShutdown(this, _ioc);
|
||||
if (TimeoutHelper.CheckDbChanged(this, _ioc))
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -93,15 +93,7 @@ namespace keepass2android
|
||||
return;
|
||||
}
|
||||
|
||||
if (App.Kp2a.GetDb() != null)
|
||||
{
|
||||
Toast.MakeText(this, GetString(Resource.String.otp_discarded_because_db_open), ToastLength.Long).Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartActivity(i);
|
||||
}
|
||||
|
||||
StartActivity(i);
|
||||
Finish();
|
||||
|
||||
}
|
||||
|
@@ -737,12 +737,6 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
if (App.Kp2a.GetDb()?.Ioc != null && App.Kp2a.GetDb().Ioc.GetDisplayName() != _ioConnection.GetDisplayName())
|
||||
{
|
||||
// A different database is currently loaded, unload it before loading the new one requested
|
||||
App.Kp2a.LockDatabase(false);
|
||||
}
|
||||
|
||||
SetContentView(Resource.Layout.password);
|
||||
|
||||
InitializeToolbar();
|
||||
@@ -807,6 +801,14 @@ namespace keepass2android
|
||||
if ((int)Build.VERSION.SdkInt >= 23)
|
||||
RequestPermissions(new[] { Manifest.Permission.UseFingerprint }, FingerprintPermissionRequestCode);
|
||||
|
||||
|
||||
var matchingOpenDb = App.Kp2a.OpenDatabases.FirstOrDefault(db => db.Ioc.IsSameFileAs(_ioConnection));
|
||||
if (matchingOpenDb != null)
|
||||
{
|
||||
App.Kp2a.CurrentDb = matchingOpenDb;
|
||||
Finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void InitializeToolbarCollapsing()
|
||||
@@ -1473,9 +1475,7 @@ namespace keepass2android
|
||||
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, GetKeyProviderString(), onFinish);
|
||||
_loadDbFileTask = null; // prevent accidental re-use
|
||||
|
||||
SetNewDefaultFile();
|
||||
|
||||
new ProgressTask(App.Kp2a, this, task).Run();
|
||||
new ProgressTask(App.Kp2a, this, task).Run();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1596,35 +1596,7 @@ namespace keepass2android
|
||||
base.OnPause();
|
||||
}
|
||||
|
||||
private void SetNewDefaultFile()
|
||||
{
|
||||
//Don't allow the current file to be the default if we don't have stored credentials
|
||||
bool makeFileDefault;
|
||||
if ((_ioConnection.IsLocalFile() == false) && (_ioConnection.CredSaveMode != IOCredSaveMode.SaveCred))
|
||||
{
|
||||
makeFileDefault = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
makeFileDefault = true;
|
||||
}
|
||||
String newDefaultFileName;
|
||||
|
||||
if (makeFileDefault)
|
||||
{
|
||||
newDefaultFileName = _ioConnection.Path;
|
||||
}
|
||||
else
|
||||
{
|
||||
newDefaultFileName = "";
|
||||
}
|
||||
|
||||
ISharedPreferencesEditor editor = _prefs.Edit();
|
||||
editor.PutString(KeyDefaultFilename, newDefaultFileName);
|
||||
EditorCompat.Apply(editor);
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
_starting = true;
|
||||
@@ -1815,34 +1787,27 @@ namespace keepass2android
|
||||
//use !performingLoad to make sure we're not already loading the database (after ActivityResult from File-Prepare-Activity; this would cause _loadDbFileTask to exist when we reload later!)
|
||||
if ( !IsFinishing && !_performingLoad)
|
||||
{
|
||||
if (App.Kp2a.DatabaseIsUnlocked)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
else if (App.Kp2a.QuickUnlockEnabled && App.Kp2a.QuickLocked)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
// OnResume is run every time the activity comes to the foreground. This code should only run when the activity is started (OnStart), but must
|
||||
// be run in OnResume rather than OnStart so that it always occurrs after OnActivityResult (when re-creating a killed activity, OnStart occurs before OnActivityResult)
|
||||
if (_starting)
|
||||
{
|
||||
|
||||
_starting = false;
|
||||
|
||||
//database not yet loaded.
|
||||
// OnResume is run every time the activity comes to the foreground. This code should only run when the activity is started (OnStart), but must
|
||||
// be run in OnResume rather than OnStart so that it always occurrs after OnActivityResult (when re-creating a killed activity, OnStart occurs before OnActivityResult)
|
||||
if (_starting)
|
||||
{
|
||||
|
||||
_starting = false;
|
||||
|
||||
//database not yet loaded.
|
||||
|
||||
//check if pre-loading is enabled but wasn't started yet:
|
||||
if (_loadDbFileTask == null &&
|
||||
_prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true))
|
||||
{
|
||||
// Create task to kick off file loading while the user enters the password
|
||||
_loadDbFileTask = Task.Factory.StartNew(PreloadDbFile);
|
||||
_loadDbTaskOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
}
|
||||
|
||||
//check if pre-loading is enabled but wasn't started yet:
|
||||
if (_loadDbFileTask == null && _prefs.GetBoolean(GetString(Resource.String.PreloadDatabaseEnabled_key), true))
|
||||
{
|
||||
// Create task to kick off file loading while the user enters the password
|
||||
_loadDbFileTask = Task.Factory.StartNew(PreloadDbFile);
|
||||
_loadDbTaskOffline = App.Kp2a.OfflineMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compositeKeyForImmediateLoad != null)
|
||||
@@ -2049,6 +2014,7 @@ namespace keepass2android
|
||||
_act.BroadcastOpenDatabase();
|
||||
_act.InvalidCompositeKeyCount = 0;
|
||||
_act.LoadingErrorCount = 0;
|
||||
_act.Finish();
|
||||
|
||||
|
||||
GC.Collect(); // Ensure temporary memory used while loading is collected
|
||||
@@ -2193,7 +2159,7 @@ namespace keepass2android
|
||||
if (!OathHotpKeyProv.CreateAuxFile(_act._otpInfo, ctx, _act._otpAuxIoc))
|
||||
Toast.MakeText(_act, _act.GetString(Resource.String.ErrorUpdatingOtpAuxFile), ToastLength.Long).Show();
|
||||
|
||||
App.Kp2a.GetDb().OtpAuxFileIoc = _act._otpAuxIoc;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -2206,7 +2172,14 @@ namespace keepass2android
|
||||
|
||||
base.Run();
|
||||
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
App.Kp2a.CurrentDb.OtpAuxFileIoc = _act._otpAuxIoc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private class PasswordActivityBroadcastReceiver : BroadcastReceiver
|
||||
{
|
||||
|
@@ -49,8 +49,8 @@ namespace keepass2android
|
||||
//if launched from history, don't re-use the task. Proceed to FileSelect instead.
|
||||
if (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory))
|
||||
{
|
||||
Kp2aLog.Log("Forwarding to FileSelect. QueryCredentialsActivity started from history.");
|
||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||
Kp2aLog.Log("Forwarding to SelectCurrentDbActivity. QueryCredentialsActivity started from history.");
|
||||
Intent intent = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(intent);
|
||||
Finish();
|
||||
@@ -135,9 +135,9 @@ namespace keepass2android
|
||||
|
||||
private void StartQuery()
|
||||
{
|
||||
//launch FileSelectActivity (which is root of the stack (exception: we're even below!)) with the appropriate task.
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof (FileSelectActivity));
|
||||
//launch SelectCurrentDbActivity (which is root of the stack (exception: we're even below!)) with the appropriate task.
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof (SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new SearchUrlTask() {UrlToSearchFor = _requestedUrl, ShowUserNotifications = false};
|
||||
task.ToIntent(i);
|
||||
@@ -185,7 +185,7 @@ namespace keepass2android
|
||||
}
|
||||
//return credentials to caller:
|
||||
Intent credentialData = new Intent();
|
||||
PluginHost.AddEntryToIntent(credentialData, App.Kp2a.GetDb().LastOpenedEntry);
|
||||
PluginHost.AddEntryToIntent(credentialData, App.Kp2a.LastOpenedEntry);
|
||||
credentialData.PutExtra(Strings.ExtraQueryString,_requestedUrl);
|
||||
SetResult(Result.Ok, credentialData);
|
||||
Finish();
|
||||
|
@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
@@ -64,7 +65,7 @@ namespace keepass2android
|
||||
Window.SetFlags(WindowManagerFlags.Secure, WindowManagerFlags.Secure);
|
||||
}
|
||||
|
||||
_ioc = App.Kp2a.GetDb().Ioc;
|
||||
_ioc = App.Kp2a.GetDbForQuickUnlock().Ioc;
|
||||
|
||||
if (_ioc == null)
|
||||
{
|
||||
@@ -81,10 +82,10 @@ namespace keepass2android
|
||||
var collapsingToolbar = FindViewById<CollapsingToolbarLayout>(Resource.Id.collapsing_toolbar);
|
||||
collapsingToolbar.SetTitle(GetString(Resource.String.QuickUnlock_prefs));
|
||||
|
||||
if (App.Kp2a.GetDb().KpDatabase.Name != "")
|
||||
if (App.Kp2a.GetDbForQuickUnlock().KpDatabase.Name != "")
|
||||
{
|
||||
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Visible;
|
||||
((TextView) FindViewById(Resource.Id.filename_label)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
||||
((TextView) FindViewById(Resource.Id.filename_label)).Text = App.Kp2a.GetDbForQuickUnlock().KpDatabase.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -134,7 +135,7 @@ namespace keepass2android
|
||||
btnLock.Text = btnLock.Text.Replace("<22>", "ss");
|
||||
btnLock.Click += (object sender, EventArgs e) =>
|
||||
{
|
||||
App.Kp2a.LockDatabase(false);
|
||||
App.Kp2a.Lock(false);
|
||||
Finish();
|
||||
};
|
||||
pwd.EditorAction += (sender, args) =>
|
||||
@@ -244,7 +245,7 @@ namespace keepass2android
|
||||
try
|
||||
{
|
||||
FingerprintUnlockMode um;
|
||||
Enum.TryParse(PreferenceManager.GetDefaultSharedPreferences(this).GetString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, ""), out um);
|
||||
Enum.TryParse(PreferenceManager.GetDefaultSharedPreferences(this).GetString(App.Kp2a.GetDbForQuickUnlock().CurrentFingerprintModePrefKey, ""), out um);
|
||||
btn.Visibility = (um != FingerprintUnlockMode.Disabled) ? ViewStates.Visible : ViewStates.Gone;
|
||||
|
||||
if (um == FingerprintUnlockMode.Disabled)
|
||||
@@ -258,10 +259,10 @@ namespace keepass2android
|
||||
FingerprintModule fpModule = new FingerprintModule(this);
|
||||
Kp2aLog.Log("fpModule.FingerprintManager.IsHardwareDetected=" + fpModule.FingerprintManager.IsHardwareDetected);
|
||||
if (fpModule.FingerprintManager.IsHardwareDetected) //see FingerprintSetupActivity
|
||||
_fingerprintIdentifier = new FingerprintDecryption(fpModule, App.Kp2a.GetDb().CurrentFingerprintPrefKey, this,
|
||||
App.Kp2a.GetDb().CurrentFingerprintPrefKey);
|
||||
_fingerprintIdentifier = new FingerprintDecryption(fpModule, App.Kp2a.GetDbForQuickUnlock().CurrentFingerprintPrefKey, this,
|
||||
App.Kp2a.GetDbForQuickUnlock().CurrentFingerprintPrefKey);
|
||||
}
|
||||
if ((_fingerprintIdentifier == null) && (!FingerprintDecryption.IsSetUp(this, App.Kp2a.GetDb().CurrentFingerprintPrefKey)))
|
||||
if ((_fingerprintIdentifier == null) && (!FingerprintDecryption.IsSetUp(this, App.Kp2a.GetDbForQuickUnlock().CurrentFingerprintPrefKey)))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -321,15 +322,7 @@ namespace keepass2android
|
||||
_fingerprintIdentifier = null;
|
||||
}
|
||||
|
||||
private void ClearFingerprintUnlockData()
|
||||
{
|
||||
ISharedPreferencesEditor edit = PreferenceManager.GetDefaultSharedPreferences(this).Edit();
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintPrefKey, "");
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, FingerprintUnlockMode.Disabled.ToString());
|
||||
edit.Commit();
|
||||
}
|
||||
|
||||
private void OnUnlock(int quickUnlockLength, EditText pwd)
|
||||
private void OnUnlock(int quickUnlockLength, EditText pwd)
|
||||
{
|
||||
var expectedPasswordPart = ExpectedPasswordPart;
|
||||
if (pwd.Text == expectedPasswordPart)
|
||||
@@ -340,7 +333,7 @@ namespace keepass2android
|
||||
else
|
||||
{
|
||||
Kp2aLog.Log("QuickUnlock not successful!");
|
||||
App.Kp2a.LockDatabase(false);
|
||||
App.Kp2a.Lock(false);
|
||||
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
||||
}
|
||||
Finish();
|
||||
@@ -350,7 +343,7 @@ namespace keepass2android
|
||||
{
|
||||
get
|
||||
{
|
||||
KcpPassword kcpPassword = (KcpPassword) App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof (KcpPassword));
|
||||
KcpPassword kcpPassword = (KcpPassword) App.Kp2a.GetDbForQuickUnlock().KpDatabase.MasterKey.GetUserKey(typeof (KcpPassword));
|
||||
String password = kcpPassword.Password.ReadString();
|
||||
|
||||
var passwordStringInfo = new System.Globalization.StringInfo(password);
|
||||
@@ -427,7 +420,7 @@ namespace keepass2android
|
||||
|
||||
private void CheckIfUnloaded()
|
||||
{
|
||||
if (App.Kp2a.GetDb() == null)
|
||||
if (App.Kp2a.OpenDatabases.Any() == false)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
|
35
src/keepass2android/Resources/layout/open_db_selection.xml
Normal file
35
src/keepass2android/Resources/layout/open_db_selection.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:background="@drawable/splash_bg_selector"
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center_horizontal">
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/mytoolbar"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||
app:titleTextStyle="@style/MyTitleTextStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:background="#00000000" />
|
||||
<GridView
|
||||
android:id="@+id/gridview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="16dp"
|
||||
android:background="@drawable/storagetype_grid_bg"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:columnWidth="140dp"
|
||||
android:numColumns="auto_fit"
|
||||
android:verticalSpacing="10dp"
|
||||
android:horizontalSpacing="10dp"
|
||||
android:stretchMode="columnWidth"
|
||||
android:gravity="center" />
|
||||
</LinearLayout>
|
@@ -57,11 +57,16 @@
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
|
||||
<item android:id="@+id/menu_sort"
|
||||
<item android:id="@+id/menu_sort"
|
||||
android:icon="@android:drawable/ic_menu_sort_by_size"
|
||||
android:title="@string/sort_menu"
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
<item android:id="@+id/menu_open_other_db"
|
||||
android:title="@string/open_other_db"
|
||||
app:showAsAction="never"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
</menu>
|
||||
|
@@ -63,6 +63,7 @@
|
||||
<string name="unlock_database_title">Unlock database</string>
|
||||
<string name="brackets">Brackets</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="Ok">Ok</string>
|
||||
<string name="ClearClipboard">Clipboard cleared.</string>
|
||||
|
||||
|
||||
@@ -210,7 +211,7 @@
|
||||
<string name="omitbackup_title">Don\'t search backup and recycle bin entries</string>
|
||||
<string name="omitbackup_summary">Omit \'Backup\' and Recycle Bin group from search results</string>
|
||||
<string name="pass_filename">KeePass database filename</string>
|
||||
<string name="password_title">Enter database password</string>
|
||||
<string name="password_title">Enter databoase password</string>
|
||||
<string name="master_key_type">Select master key type:</string>
|
||||
<string name="progress_create">Creating new database…</string>
|
||||
<string name="create_database">Create database</string>
|
||||
@@ -430,6 +431,10 @@
|
||||
<string name="AskOverwriteBinary_no">Rename</string>
|
||||
<string name="AttachFailed">Failed to add file attachment.</string>
|
||||
<string name="RecycleBin">Recycle Bin</string>
|
||||
|
||||
<string name="UpdatingTemplateIds">Updating template entries </string>
|
||||
|
||||
|
||||
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</string>
|
||||
<string name="AskDeletePermanentlyGroup">Do you want to delete this group permanently? Press No to recycle.</string>
|
||||
<string name="AskDeletePermanentlyItems">Do you want to delete the selected elements permanently? Press No to recycle.</string>
|
||||
@@ -731,6 +736,12 @@
|
||||
|
||||
</string>
|
||||
|
||||
<string name="open_other_db">Open another database…</string>
|
||||
<string name="select_database">Select database</string>
|
||||
|
||||
<string name="ChangleLegacyTemplateIds_Title">Identical template entry ids</string>
|
||||
<string name="ChangleLegacyTemplateIds_Message">Your database contains template entries with the same UUIDs as template entries in another open database. In order to use both databases simultaneously, Keepass2Android will modify the IDs of the database you are about to open.</string>
|
||||
|
||||
<string name="DbUnlockedChannel_name">Database unlocked</string>
|
||||
<string name="DbUnlockedChannel_desc">Notification about the database being unlocked</string>
|
||||
|
||||
|
@@ -6,25 +6,155 @@ using System.Text;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Graphics;
|
||||
using Android.Graphics.Drawables;
|
||||
using Android.OS;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using Android.Support.V7.App;
|
||||
using Android.Text;
|
||||
using Android.Util;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.Io;
|
||||
using keepass2android.Utils;
|
||||
using KeeChallenge;
|
||||
using KeePassLib.Keys;
|
||||
using KeePassLib.Serialization;
|
||||
using Object = Java.Lang.Object;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
[Activity(Label = AppNames.AppName, MainLauncher = false, Theme = "@style/MyTheme_Blue", LaunchMode = LaunchMode.SingleInstance)]
|
||||
public class SelectCurrentDbActivity : Activity
|
||||
public class SelectCurrentDbActivity : AppCompatActivity
|
||||
{
|
||||
public class OpenDatabaseAdapter : BaseAdapter
|
||||
{
|
||||
|
||||
private readonly SelectCurrentDbActivity _context;
|
||||
internal List<Database> _displayedDatabases;
|
||||
|
||||
public OpenDatabaseAdapter(SelectCurrentDbActivity context)
|
||||
{
|
||||
_context = context;
|
||||
Update();
|
||||
|
||||
}
|
||||
|
||||
public override Object GetItem(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
public override long GetItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static float convertDpToPixel(float dp, Context context)
|
||||
{
|
||||
return Util.convertDpToPixel(dp, context);
|
||||
}
|
||||
|
||||
|
||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
|
||||
Button btn;
|
||||
|
||||
if (convertView == null)
|
||||
{
|
||||
// if it's not recycled, initialize some attributes
|
||||
|
||||
btn = new Button(_context);
|
||||
btn.LayoutParameters = new GridView.LayoutParams((int) convertDpToPixel(140, _context),
|
||||
(int) convertDpToPixel(150, _context));
|
||||
btn.SetBackgroundResource(Resource.Drawable.storagetype_button_bg);
|
||||
btn.SetPadding((int) convertDpToPixel(4, _context),
|
||||
(int) convertDpToPixel(20, _context),
|
||||
(int) convertDpToPixel(4, _context),
|
||||
(int) convertDpToPixel(4, _context));
|
||||
btn.SetTextSize(ComplexUnitType.Sp, 11);
|
||||
btn.SetTextColor(new Color(115, 115, 115));
|
||||
btn.SetSingleLine(false);
|
||||
btn.Gravity = GravityFlags.Center;
|
||||
btn.Click += (sender, args) =>
|
||||
{
|
||||
int pos;
|
||||
int.TryParse(((Button) sender).Tag.ToString(), out pos);
|
||||
if (pos < _displayedDatabases.Count)
|
||||
_context.OnItemSelected(_displayedDatabases[pos]);
|
||||
else
|
||||
{
|
||||
_context.OnOpenOther();
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
btn = (Button) convertView;
|
||||
}
|
||||
|
||||
btn.Tag = position.ToString();
|
||||
|
||||
string displayName;
|
||||
Drawable drawable;
|
||||
if (position < _displayedDatabases.Count)
|
||||
{
|
||||
var db = _displayedDatabases[position];
|
||||
drawable = App.Kp2a.GetResourceDrawable("ic_storage_" + Util.GetProtocolId(db.Ioc));
|
||||
displayName = db.KpDatabase.Name;
|
||||
displayName += "\n" + App.Kp2a.GetFileStorage(db.Ioc).GetDisplayName(db.Ioc);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayName = _context.GetString(Resource.String.start_open_file);
|
||||
drawable = App.Kp2a.GetResourceDrawable("ic_nav_changedb");
|
||||
}
|
||||
|
||||
var str = new SpannableString(displayName);
|
||||
|
||||
btn.TextFormatted = str;
|
||||
//var drawable = ContextCompat.GetDrawable(context, Resource.Drawable.Icon);
|
||||
btn.SetCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return _displayedDatabases.Count+1; }
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
_displayedDatabases = App.Kp2a.OpenDatabases.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpenOther()
|
||||
{
|
||||
StartFileSelect();
|
||||
}
|
||||
|
||||
private void OnItemSelected(Database selectedDatabase)
|
||||
{
|
||||
App.Kp2a.CurrentDb = selectedDatabase;
|
||||
AppTask.LaunchFirstGroupActivity(this);
|
||||
}
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
SetContentView(Resource.Layout.open_db_selection);
|
||||
|
||||
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.mytoolbar);
|
||||
|
||||
SetSupportActionBar(toolbar);
|
||||
|
||||
SupportActionBar.Title = GetString(Resource.String.select_database);
|
||||
|
||||
if ((AppTask == null) && (Intent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory)))
|
||||
{
|
||||
AppTask = new NullTask();
|
||||
@@ -33,6 +163,12 @@ namespace keepass2android
|
||||
{
|
||||
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||
}
|
||||
|
||||
_adapter = new OpenDatabaseAdapter(this);
|
||||
var gridView = FindViewById<GridView>(Resource.Id.gridview);
|
||||
gridView.ItemClick += (sender, args) => OnItemSelected(_adapter._displayedDatabases[args.Position]);
|
||||
gridView.Adapter = _adapter;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -44,54 +180,78 @@ namespace keepass2android
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
if (!IsFinishing)
|
||||
if (!IsFinishing && !LaunchingPasswordActivity)
|
||||
{
|
||||
if (App.Kp2a.GetDb() == null)
|
||||
if (App.Kp2a.OpenDatabases.Any() == false)
|
||||
{
|
||||
// Load default database
|
||||
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(this);
|
||||
String defaultFileName = prefs.GetString(PasswordActivity.KeyDefaultFilename, "");
|
||||
|
||||
if (defaultFileName.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
PasswordActivity.Launch(this, LoadIoc(defaultFileName), AppTask);
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Toast.MakeText(this, e.Message, ToastLength.Long);
|
||||
// Ignore exception
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||
AppTask.ToIntent(intent);
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(intent);
|
||||
StartFileSelect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_loadAnotherDatabase)
|
||||
{
|
||||
StartFileSelect();
|
||||
_loadAnotherDatabase = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//database loaded
|
||||
if (App.Kp2a.QuickLocked)
|
||||
{
|
||||
var i = new Intent(this, typeof(QuickUnlock));
|
||||
Util.PutIoConnectionToIntent(App.Kp2a.GetDb().Ioc, i);
|
||||
Util.PutIoConnectionToIntent(App.Kp2a.GetDbForQuickUnlock().Ioc, i);
|
||||
Kp2aLog.Log("Starting QuickUnlock");
|
||||
StartActivityForResult(i, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
//database(s) unlocked
|
||||
if (App.Kp2a.OpenDatabases.Count() == 1)
|
||||
{
|
||||
AppTask.LaunchFirstGroupActivity(this);
|
||||
return;
|
||||
}
|
||||
|
||||
//more than one database open or user requested to load another db. Don't launch another activity.
|
||||
_adapter.Update();
|
||||
_adapter.NotifyDataSetChanged();
|
||||
|
||||
|
||||
}
|
||||
base.OnResume();
|
||||
}
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
LaunchingPasswordActivity = false;
|
||||
base.OnPause();
|
||||
}
|
||||
|
||||
private void StartFileSelect()
|
||||
{
|
||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||
AppTask.ToIntent(intent);
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(intent);
|
||||
}
|
||||
|
||||
internal AppTask AppTask;
|
||||
private bool _loadAnotherDatabase;
|
||||
private OpenDatabaseAdapter _adapter;
|
||||
|
||||
public override void OnBackPressed()
|
||||
{
|
||||
base.OnBackPressed();
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.LockWhenNavigateBack_key), false))
|
||||
{
|
||||
App.Kp2a.Lock();
|
||||
}
|
||||
//by leaving the app with the back button, the user probably wants to cancel the task
|
||||
//The activity might be resumed (through Android's recent tasks list), then use a NullTask:
|
||||
AppTask = new NullTask();
|
||||
Finish();
|
||||
}
|
||||
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
@@ -104,15 +264,10 @@ namespace keepass2android
|
||||
switch (resultCode)
|
||||
{
|
||||
case KeePass.ExitNormal: // Returned to this screen using the Back key
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.LockWhenNavigateBack_key), false))
|
||||
if (App.Kp2a.OpenDatabases.Count() == 1)
|
||||
{
|
||||
App.Kp2a.LockDatabase();
|
||||
OnBackPressed();
|
||||
}
|
||||
//by leaving the app with the back button, the user probably wants to cancel the task
|
||||
//The activity might be resumed (through Android's recent tasks list), then use a NullTask:
|
||||
AppTask = new NullTask();
|
||||
Finish();
|
||||
break;
|
||||
case KeePass.ExitLock:
|
||||
// The database has already been locked, and the quick unlock screen will be shown if appropriate
|
||||
@@ -128,18 +283,21 @@ namespace keepass2android
|
||||
break;
|
||||
case KeePass.ExitReloadDb:
|
||||
|
||||
if (App.Kp2a.GetDb() != null)
|
||||
if (App.Kp2a.CurrentDb!= null)
|
||||
{
|
||||
//remember the composite key for reloading:
|
||||
var compositeKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
||||
var ioc = App.Kp2a.GetDb().Ioc;
|
||||
var compositeKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
||||
var ioc = App.Kp2a.CurrentDb.Ioc;
|
||||
|
||||
//lock the database:
|
||||
App.Kp2a.LockDatabase(false);
|
||||
App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
|
||||
|
||||
LaunchPasswordActivityForReload(ioc, compositeKey);
|
||||
}
|
||||
|
||||
break;
|
||||
case KeePass.ExitLoadAnotherDb:
|
||||
_loadAnotherDatabase = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -147,7 +305,10 @@ namespace keepass2android
|
||||
|
||||
private void LaunchPasswordActivityForReload(IOConnectionInfo ioc, CompositeKey compositeKey)
|
||||
{
|
||||
LaunchingPasswordActivity = true;
|
||||
PasswordActivity.Launch(this, ioc, AppTask, compositeKey);
|
||||
}
|
||||
|
||||
public bool LaunchingPasswordActivity { get; set; }
|
||||
}
|
||||
}
|
@@ -104,13 +104,13 @@ namespace keepass2android
|
||||
_finish.Filename = _dlg.Keyfile;
|
||||
}
|
||||
FingerprintUnlockMode um;
|
||||
Enum.TryParse(PreferenceManager.GetDefaultSharedPreferences(_dlg.Context).GetString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, ""), out um);
|
||||
Enum.TryParse(PreferenceManager.GetDefaultSharedPreferences(_dlg.Context).GetString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, ""), out um);
|
||||
|
||||
if (um == FingerprintUnlockMode.FullUnlock)
|
||||
{
|
||||
ISharedPreferencesEditor edit = PreferenceManager.GetDefaultSharedPreferences(_dlg.Context).Edit();
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintPrefKey, "");
|
||||
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, FingerprintUnlockMode.Disabled.ToString());
|
||||
edit.PutString(App.Kp2a.CurrentDb.CurrentFingerprintPrefKey, "");
|
||||
edit.PutString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, FingerprintUnlockMode.Disabled.ToString());
|
||||
edit.Commit();
|
||||
|
||||
Toast.MakeText(_dlg.Context, Resource.String.fingerprint_reenable, ToastLength.Long).Show();
|
||||
|
@@ -26,6 +26,7 @@ using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.Content.PM;
|
||||
using Android.Preferences;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Utility;
|
||||
|
||||
namespace keepass2android
|
||||
@@ -63,9 +64,6 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
private Database _db;
|
||||
|
||||
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
get { return true; }
|
||||
@@ -78,8 +76,6 @@ namespace keepass2android
|
||||
//if user presses back to leave this activity:
|
||||
SetResult(Result.Canceled);
|
||||
|
||||
_db = App.Kp2a.GetDb();
|
||||
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.select_other_entry, true);
|
||||
UpdateBottomBarElementVisibility(Resource.Id.add_url_entry, true);
|
||||
@@ -107,24 +103,41 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
//first: search for exact url
|
||||
Group = _db.SearchForExactUrl(url);
|
||||
if (!url.StartsWith("androidapp://"))
|
||||
{
|
||||
//if no results, search for host (e.g. "accounts.google.com")
|
||||
if (!Group.Entries.Any())
|
||||
Group = _db.SearchForHost(url, false);
|
||||
//if still no results, search for host, allowing subdomains ("www.google.com" in entry is ok for "accounts.google.com" in search (but not the other way around)
|
||||
if (!Group.Entries.Any())
|
||||
Group = _db.SearchForHost(url, true);
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
PwGroup resultsForThisDb;
|
||||
//first: search for exact url
|
||||
resultsForThisDb = db.SearchForExactUrl(url);
|
||||
if (!url.StartsWith("androidapp://"))
|
||||
{
|
||||
//if no results, search for host (e.g. "accounts.google.com")
|
||||
if (!resultsForThisDb.Entries.Any())
|
||||
resultsForThisDb = db.SearchForHost(url, false);
|
||||
//if still no results, search for host, allowing subdomains ("www.google.com" in entry is ok for "accounts.google.com" in search (but not the other way around)
|
||||
if (!resultsForThisDb.Entries.Any())
|
||||
resultsForThisDb = db.SearchForHost(url, true);
|
||||
|
||||
}
|
||||
//if no results returned up to now, try to search through other fields as well:
|
||||
if (!Group.Entries.Any())
|
||||
Group = _db.SearchForText(url);
|
||||
//search for host as text
|
||||
if (!Group.Entries.Any())
|
||||
Group = _db.SearchForText(UrlUtil.GetHost(url.Trim()));
|
||||
}
|
||||
//if no results returned up to now, try to search through other fields as well:
|
||||
if (!resultsForThisDb.Entries.Any())
|
||||
resultsForThisDb = db.SearchForText(url);
|
||||
//search for host as text
|
||||
if (!resultsForThisDb.Entries.Any())
|
||||
resultsForThisDb = db.SearchForText(UrlUtil.GetHost(url.Trim()));
|
||||
|
||||
if (Group == null)
|
||||
{
|
||||
Group = resultsForThisDb;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var entry in resultsForThisDb.Entries)
|
||||
{
|
||||
Group.AddEntry(entry, false,false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
@@ -164,7 +177,7 @@ namespace keepass2android
|
||||
|
||||
View createUrlEntry = FindViewById (Resource.Id.add_url_entry);
|
||||
|
||||
if (App.Kp2a.GetDb().CanWrite)
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Visible;
|
||||
createUrlEntry.Click += (sender, e) =>
|
||||
@@ -194,5 +207,10 @@ namespace keepass2android
|
||||
{
|
||||
get { return Resource.Layout.searchurlresults; }
|
||||
}
|
||||
|
||||
public override bool EntriesBelongToCurrentDatabaseOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}}
|
||||
|
||||
|
@@ -13,10 +13,12 @@ namespace keepass2android
|
||||
readonly ITotpPluginAdapter[] _pluginAdapters = new ITotpPluginAdapter[] { new TrayTotpPluginAdapter(), new KeeOtpPluginAdapter(), new KeeWebOtpPluginAdapter() };
|
||||
|
||||
public void OnOpenEntry()
|
||||
{
|
||||
foreach (ITotpPluginAdapter adapter in _pluginAdapters)
|
||||
{
|
||||
if (App.Kp2a.LastOpenedEntry == null)
|
||||
return;
|
||||
foreach (ITotpPluginAdapter adapter in _pluginAdapters)
|
||||
{
|
||||
TotpData totpData = adapter.GetTotpData(App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString()), Application.Context, false);
|
||||
TotpData totpData = adapter.GetTotpData(App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString()), Application.Context, false);
|
||||
if (totpData.IsTotpEnry)
|
||||
{
|
||||
new UpdateTotpTimerTask(Application.Context, adapter).Run();
|
||||
|
@@ -27,10 +27,10 @@ namespace PluginTOTP
|
||||
{
|
||||
try
|
||||
{
|
||||
if (App.Kp2a.GetDb().LastOpenedEntry == null)
|
||||
if (App.Kp2a.LastOpenedEntry == null)
|
||||
return; //DB was locked
|
||||
|
||||
Dictionary<string, string> entryFields = App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString());
|
||||
Dictionary<string, string> entryFields = App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString());
|
||||
//mute warnings to avoid repeated display of the toasts
|
||||
TotpData totpData = _adapter.GetTotpData(entryFields, _context, true /*mute warnings*/);
|
||||
if (totpData.IsTotpEnry)
|
||||
@@ -58,10 +58,10 @@ namespace PluginTOTP
|
||||
private void UpdateEntryData(string totp)
|
||||
{
|
||||
//update the Entry output in the App database and notify the CopyToClipboard service
|
||||
App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.Set(_totp, new ProtectedString(true, totp));
|
||||
App.Kp2a.LastOpenedEntry.OutputStrings.Set(_totp, new ProtectedString(true, totp));
|
||||
Intent updateKeyboardIntent = new Intent(_context, typeof(CopyToClipboardService));
|
||||
updateKeyboardIntent.SetAction(Intents.UpdateKeyboard);
|
||||
updateKeyboardIntent.PutExtra("entry", App.Kp2a.GetDb().LastOpenedEntry.Uuid.ToHexString());
|
||||
updateKeyboardIntent.PutExtra("entry", App.Kp2a.LastOpenedEntry.Uuid.ToHexString());
|
||||
_context.StartService(updateKeyboardIntent);
|
||||
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace PluginTOTP
|
||||
i.SetPackage(_context.PackageName);
|
||||
i.PutExtra(Strings.ExtraSender, _context.PackageName);
|
||||
i.PutExtra(Strings.ExtraFieldValue, totp);
|
||||
i.PutExtra(Strings.ExtraEntryId, App.Kp2a.GetDb().LastOpenedEntry.Entry.Uuid.ToHexString());
|
||||
i.PutExtra(Strings.ExtraEntryId, App.Kp2a.LastOpenedEntry.Entry.Uuid.ToHexString());
|
||||
i.PutExtra(Strings.ExtraFieldId, _totp);
|
||||
i.PutExtra(Strings.ExtraFieldProtected, true);
|
||||
|
||||
|
@@ -46,20 +46,20 @@ namespace keepass2android
|
||||
public const String KeyServercredmode = "serverCredRememberMode";
|
||||
|
||||
|
||||
public static void PutIoConnectionToIntent(IOConnectionInfo ioc, Intent i)
|
||||
public static void PutIoConnectionToIntent(IOConnectionInfo ioc, Intent i, string prefix="")
|
||||
{
|
||||
i.PutExtra(KeyFilename, ioc.Path);
|
||||
i.PutExtra(KeyServerusername, ioc.UserName);
|
||||
i.PutExtra(KeyServerpassword, ioc.Password);
|
||||
i.PutExtra(KeyServercredmode, (int)ioc.CredSaveMode);
|
||||
i.PutExtra(prefix+KeyFilename, ioc.Path);
|
||||
i.PutExtra(prefix + KeyServerusername, ioc.UserName);
|
||||
i.PutExtra(prefix + KeyServerpassword, ioc.Password);
|
||||
i.PutExtra(prefix + KeyServercredmode, (int)ioc.CredSaveMode);
|
||||
}
|
||||
|
||||
public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i)
|
||||
public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i, string prefix="")
|
||||
{
|
||||
ioc.Path = i.GetStringExtra(KeyFilename);
|
||||
ioc.UserName = i.GetStringExtra(KeyServerusername) ?? "";
|
||||
ioc.Password = i.GetStringExtra(KeyServerpassword) ?? "";
|
||||
ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KeyServercredmode, (int)IOCredSaveMode.NoSave);
|
||||
ioc.Path = i.GetStringExtra(prefix + KeyFilename);
|
||||
ioc.UserName = i.GetStringExtra(prefix + KeyServerusername) ?? "";
|
||||
ioc.Password = i.GetStringExtra(prefix + KeyServerpassword) ?? "";
|
||||
ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(prefix + KeyServercredmode, (int)IOCredSaveMode.NoSave);
|
||||
}
|
||||
|
||||
public static Bitmap DrawableToBitmap(Drawable drawable)
|
||||
@@ -558,6 +558,15 @@ namespace keepass2android
|
||||
int width = (int)(0.9 * context.Resources.GetDimension(Android.Resource.Dimension.NotificationLargeIconWidth));
|
||||
return Bitmap.CreateScaledBitmap(unscaled, width, height, true);
|
||||
}
|
||||
|
||||
public static string GetProtocolId(IOConnectionInfo ioc)
|
||||
{
|
||||
string displayPath = App.Kp2a.GetFileStorage(ioc).GetDisplayName(ioc);
|
||||
int protocolSeparatorPos = displayPath.IndexOf("://", StringComparison.Ordinal);
|
||||
string protocolId = protocolSeparatorPos < 0 ?
|
||||
"file" : displayPath.Substring(0, protocolSeparatorPos);
|
||||
return protocolId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Security;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
@@ -40,6 +41,7 @@ using TwofishCipher;
|
||||
using Keepass2android.Pluginsdk;
|
||||
using keepass2android.Io;
|
||||
using keepass2android.addons.OtpKeyProv;
|
||||
using keepass2android.database.edit;
|
||||
using KeePassLib.Interfaces;
|
||||
using KeePassLib.Utility;
|
||||
#if !NoNet
|
||||
@@ -100,19 +102,19 @@ namespace keepass2android
|
||||
/// </summary>
|
||||
public class Kp2aApp: IKp2aApp, ICacheSupervisor
|
||||
{
|
||||
public void LockDatabase(bool allowQuickUnlock = true)
|
||||
{
|
||||
if (GetDb() != null)
|
||||
public void Lock(bool allowQuickUnlock = true)
|
||||
{
|
||||
if (OpenDatabases.Any())
|
||||
{
|
||||
if (QuickUnlockEnabled && allowQuickUnlock &&
|
||||
GetDb().KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)) &&
|
||||
!((KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword))).Password.IsEmpty)
|
||||
GetDbForQuickUnlock().KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)) &&
|
||||
!((KcpPassword)App.Kp2a.GetDbForQuickUnlock().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword))).Password.IsEmpty)
|
||||
{
|
||||
if (!QuickLocked)
|
||||
{
|
||||
Kp2aLog.Log("QuickLocking database");
|
||||
QuickLocked = true;
|
||||
GetDb().LastOpenedEntry = null;
|
||||
LastOpenedEntry = null;
|
||||
BroadcastDatabaseAction(Application.Context, Strings.ActionLockDatabase);
|
||||
}
|
||||
else
|
||||
@@ -126,8 +128,10 @@ namespace keepass2android
|
||||
|
||||
BroadcastDatabaseAction(Application.Context, Strings.ActionCloseDatabase);
|
||||
|
||||
// Couldn't quick-lock, so unload database instead
|
||||
_db = null;
|
||||
// Couldn't quick-lock, so unload database(s) instead
|
||||
_openDatabases.Clear();
|
||||
_currentDatabase = null;
|
||||
LastOpenedEntry = null;
|
||||
QuickLocked = false;
|
||||
}
|
||||
}
|
||||
@@ -143,28 +147,24 @@ namespace keepass2android
|
||||
|
||||
public void BroadcastDatabaseAction(Context ctx, string action)
|
||||
{
|
||||
Intent i = new Intent(action);
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
Intent i = new Intent(action);
|
||||
|
||||
//seems like this can happen. This code is for debugging.
|
||||
if (App.Kp2a.GetDb().Ioc == null)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(new Exception("App.Kp2a.GetDb().Ioc is null"));
|
||||
return;
|
||||
}
|
||||
i.PutExtra(Strings.ExtraDatabaseFileDisplayname, GetFileStorage(db.Ioc).GetDisplayName(db.Ioc));
|
||||
i.PutExtra(Strings.ExtraDatabaseFilepath, db.Ioc.Path);
|
||||
foreach (var plugin in new PluginDatabase(ctx).GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions))
|
||||
{
|
||||
i.SetPackage(plugin);
|
||||
ctx.SendBroadcast(i);
|
||||
}
|
||||
}
|
||||
|
||||
i.PutExtra(Strings.ExtraDatabaseFileDisplayname, App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc).GetDisplayName(App.Kp2a.GetDb().Ioc));
|
||||
i.PutExtra(Strings.ExtraDatabaseFilepath, App.Kp2a.GetDb().Ioc.Path);
|
||||
foreach (var plugin in new PluginDatabase(ctx).GetPluginsWithAcceptedScope(Strings.ScopeDatabaseActions))
|
||||
{
|
||||
i.SetPackage(plugin);
|
||||
ctx.SendBroadcast(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey,
|
||||
ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat)
|
||||
public Database LoadDatabase(IOConnectionInfo ioConnectionInfo, MemoryStream memoryStream, CompositeKey compositeKey, ProgressDialogStatusLogger statusLogger, IDatabaseFormat databaseFormat)
|
||||
{
|
||||
var prefs = PreferenceManager.GetDefaultSharedPreferences(Application.Context);
|
||||
var createBackup = prefs.GetBoolean(Application.Context.GetString(Resource.String.CreateBackups_key), true)
|
||||
@@ -180,10 +180,27 @@ namespace keepass2android
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
_db = CreateNewDatabase();
|
||||
_db.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseFormat);
|
||||
foreach (Database openDb in _openDatabases)
|
||||
{
|
||||
if (openDb.Ioc.IsSameFileAs(ioConnectionInfo))
|
||||
{
|
||||
//TODO check this earlier and simply open the database's root group
|
||||
throw new Exception("Database already loaded!");
|
||||
}
|
||||
|
||||
if (createBackup)
|
||||
}
|
||||
|
||||
var newDb = new Database(new DrawableFactory(), this);
|
||||
newDb.LoadData(this, ioConnectionInfo, memoryStream, compositeKey, statusLogger, databaseFormat);
|
||||
|
||||
|
||||
|
||||
_currentDatabase = newDb;
|
||||
_openDatabases.Add(newDb);
|
||||
|
||||
|
||||
|
||||
if (createBackup)
|
||||
{
|
||||
statusLogger.UpdateMessage(Application.Context.GetString(Resource.String.UpdatingBackup));
|
||||
Java.IO.File internalDirectory = IoUtil.GetInternalDirectory(Application.Context);
|
||||
@@ -201,9 +218,12 @@ namespace keepass2android
|
||||
|
||||
using (var transaction = new LocalFileStorage(App.Kp2a).OpenWriteTransaction(targetIoc, false))
|
||||
{
|
||||
var file = transaction.OpenFile();
|
||||
backupCopy.CopyTo(file);
|
||||
transaction.CommitWrite();
|
||||
using (var file = transaction.OpenFile())
|
||||
{
|
||||
backupCopy.CopyTo(file);
|
||||
transaction.CommitWrite();
|
||||
}
|
||||
|
||||
}
|
||||
Java.Lang.Object baseIocDisplayName = baseDisplayName;
|
||||
|
||||
@@ -226,9 +246,53 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
UpdateOngoingNotification();
|
||||
}
|
||||
|
||||
internal void UnlockDatabase()
|
||||
return newDb;
|
||||
}
|
||||
|
||||
public Database FindDatabaseForEntryId(PwUuid entryKey)
|
||||
{
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
if (db.Entries.ContainsKey(entryKey))
|
||||
return db;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void CloseDatabase(Database db)
|
||||
{
|
||||
if (!_openDatabases.Contains(db))
|
||||
throw new Exception("Cannot close database which is not open!");
|
||||
if (_openDatabases.Count == 1)
|
||||
{
|
||||
Lock(false);
|
||||
return;
|
||||
}
|
||||
if (LastOpenedEntry != null && db.Entries.ContainsKey(LastOpenedEntry.Uuid))
|
||||
{
|
||||
LastOpenedEntry = null;
|
||||
}
|
||||
|
||||
_openDatabases.Remove(db);
|
||||
if (_currentDatabase == db)
|
||||
_currentDatabase = _openDatabases.First();
|
||||
UpdateOngoingNotification();
|
||||
//TODO broadcast event so affected activities can close/update?
|
||||
}
|
||||
|
||||
public Database FindDatabaseForGroupId(PwUuid groupKey)
|
||||
{
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
if (db.Groups.ContainsKey(groupKey))
|
||||
return db;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal void UnlockDatabase()
|
||||
{
|
||||
QuickLocked = false;
|
||||
|
||||
@@ -258,7 +322,7 @@ namespace keepass2android
|
||||
|
||||
public bool DatabaseIsUnlocked
|
||||
{
|
||||
get { return GetDb() != null && !QuickLocked; }
|
||||
get { return OpenDatabases.Any() && !QuickLocked; }
|
||||
}
|
||||
|
||||
#region QuickUnlock
|
||||
@@ -287,8 +351,6 @@ namespace keepass2android
|
||||
|
||||
#endregion
|
||||
|
||||
private Database _db;
|
||||
|
||||
/// <summary>
|
||||
/// See comments to EntryEditActivityState.
|
||||
/// </summary>
|
||||
@@ -297,10 +359,50 @@ namespace keepass2android
|
||||
public FileDbHelper FileDbHelper;
|
||||
private List<IFileStorage> _fileStorages;
|
||||
|
||||
public Database GetDb()
|
||||
{
|
||||
return _db;
|
||||
}
|
||||
private readonly List<Database> _openDatabases = new List<Database>();
|
||||
private Database _currentDatabase;
|
||||
|
||||
public IEnumerable<Database> OpenDatabases
|
||||
{
|
||||
get { return _openDatabases; }
|
||||
}
|
||||
|
||||
public readonly HashSet<PwGroup> dirty = new HashSet<PwGroup>(new PwGroupEqualityFromIdComparer());
|
||||
public HashSet<PwGroup> DirtyGroups { get { return dirty; } }
|
||||
|
||||
|
||||
public void MarkAllGroupsAsDirty()
|
||||
{
|
||||
foreach (var db in OpenDatabases)
|
||||
foreach (PwGroup group in db.Groups.Values)
|
||||
{
|
||||
DirtyGroups.Add(group);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Information about the last opened entry. Includes the entry but also transformed fields.
|
||||
/// </summary>
|
||||
public PwEntryOutput LastOpenedEntry { get; set; }
|
||||
|
||||
public Database CurrentDb
|
||||
{
|
||||
get { return _currentDatabase; }
|
||||
set
|
||||
{
|
||||
if (!OpenDatabases.Contains(value))
|
||||
throw new Exception("Cannot set database as current. Not in list of opened databases!");
|
||||
_currentDatabase = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Database GetDbForQuickUnlock()
|
||||
{
|
||||
return OpenDatabases.FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -325,19 +427,28 @@ namespace keepass2android
|
||||
|
||||
public void CheckForOpenFileChanged(Activity activity)
|
||||
{
|
||||
if (GetDb()?.DidOpenFileChange() == true)
|
||||
if (CurrentDb?.DidOpenFileChange() == true)
|
||||
{
|
||||
if (GetDb().ReloadRequested)
|
||||
if (CurrentDb.ReloadRequested)
|
||||
{
|
||||
LockDatabase(false);
|
||||
activity.SetResult(KeePass.ExitReloadDb);
|
||||
activity.Finish();
|
||||
}
|
||||
AskForReload(activity);
|
||||
else
|
||||
{
|
||||
AskForReload(activity);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void AskForReload(Activity activity)
|
||||
public void LockSingleDatabase(Database databaseToLock, bool allowQuickUnlock)
|
||||
{
|
||||
//TODO implement
|
||||
throw new Exception("lock single is not implemented");
|
||||
}
|
||||
|
||||
private void AskForReload(Activity activity)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
|
||||
@@ -347,7 +458,7 @@ namespace keepass2android
|
||||
builder.SetPositiveButton(activity.GetString(Android.Resource.String.Yes),
|
||||
(dlgSender, dlgEvt) =>
|
||||
{
|
||||
GetDb().ReloadRequested = true;
|
||||
CurrentDb.ReloadRequested = true;
|
||||
activity.SetResult(KeePass.ExitReloadDb);
|
||||
activity.Finish();
|
||||
|
||||
@@ -724,7 +835,8 @@ namespace keepass2android
|
||||
internal void OnTerminate()
|
||||
{
|
||||
|
||||
_db = null;
|
||||
_openDatabases.Clear();
|
||||
_currentDatabase = null;
|
||||
|
||||
if (FileDbHelper != null && FileDbHelper.IsOpen())
|
||||
{
|
||||
@@ -752,8 +864,9 @@ namespace keepass2android
|
||||
|
||||
public Database CreateNewDatabase()
|
||||
{
|
||||
_db = new Database(new DrawableFactory(), this);
|
||||
return _db;
|
||||
_currentDatabase = new Database(new DrawableFactory(), this);
|
||||
_openDatabases.Add(_currentDatabase);
|
||||
return _currentDatabase;
|
||||
}
|
||||
|
||||
internal void ShowToast(string message)
|
||||
@@ -893,10 +1006,45 @@ namespace keepass2android
|
||||
Application.Context.GetString(Resource.String.LockWhenScreenOff_key),
|
||||
false))
|
||||
{
|
||||
App.Kp2a.LockDatabase();
|
||||
App.Kp2a.Lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Database GetDatabase(IOConnectionInfo dbIoc)
|
||||
{
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
if (db.Ioc.IsSameFileAs(dbIoc))
|
||||
return db;
|
||||
}
|
||||
throw new Exception("Database not found for dbIoc!");
|
||||
}
|
||||
|
||||
public PwGroup FindGroup(PwUuid uuid)
|
||||
{
|
||||
PwGroup result;
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
if (db.Groups.TryGetValue(uuid, out result))
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public IStructureItem FindStructureItem(PwUuid uuid)
|
||||
{
|
||||
|
||||
foreach (Database db in OpenDatabases)
|
||||
{
|
||||
PwGroup resultGroup;
|
||||
if (db.Groups.TryGetValue(uuid, out resultGroup))
|
||||
return resultGroup;
|
||||
PwEntry resultEntry;
|
||||
if (db.Entries.TryGetValue(uuid, out resultEntry))
|
||||
return resultEntry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///Application class for Keepass2Android: Contains static Database variable to be used by all components.
|
||||
|
@@ -344,7 +344,7 @@ namespace keepass2android
|
||||
activity.StartNotificationsService(false);
|
||||
}
|
||||
|
||||
virtual public void PopulatePasswordAccessServiceIntent(Intent intent)
|
||||
public virtual void PopulatePasswordAccessServiceIntent(Intent intent)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -434,7 +434,8 @@ namespace keepass2android
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
App.Kp2a.GetDb().LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
}
|
||||
}
|
||||
@@ -554,10 +555,11 @@ namespace keepass2android
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
{
|
||||
App.Kp2a.GetDb().LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
|
||||
//if the database is readonly (or no URL exists), don't offer to modify the URL
|
||||
if ((App.Kp2a.GetDb().CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor)))
|
||||
if ((App.Kp2a.CurrentDb.CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor)))
|
||||
{
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
return;
|
||||
@@ -790,7 +792,8 @@ namespace keepass2android
|
||||
#endif
|
||||
|
||||
private LinkedList<string> _groupUuid;
|
||||
protected AppTask TaskToBeLaunchedAfterNavigation;
|
||||
private readonly Database _db;
|
||||
protected AppTask TaskToBeLaunchedAfterNavigation;
|
||||
|
||||
protected String FullGroupName {
|
||||
get ;
|
||||
@@ -814,8 +817,9 @@ namespace keepass2android
|
||||
/// <param name="groups">Groups.</param>
|
||||
/// <param name="taskToBeLaunchedAfterNavigation">Task to be launched after navigation.</param>
|
||||
/// <param name="toastEnable">If set to <c>true</c>, toast will be displayed after navigation.</param>
|
||||
protected NavigateAndLaunchTask(PwGroup groups, AppTask taskToBeLaunchedAfterNavigation, bool toastEnable = false) {
|
||||
TaskToBeLaunchedAfterNavigation = taskToBeLaunchedAfterNavigation;
|
||||
protected NavigateAndLaunchTask(Database db, PwGroup groups, AppTask taskToBeLaunchedAfterNavigation, bool toastEnable = false) {
|
||||
_db = db;
|
||||
TaskToBeLaunchedAfterNavigation = taskToBeLaunchedAfterNavigation;
|
||||
PopulateGroups (groups);
|
||||
ToastEnable = toastEnable;
|
||||
}
|
||||
@@ -943,7 +947,7 @@ namespace keepass2android
|
||||
PwUuid nextGroupPwUuid = new PwUuid (MemUtil.HexStringToByteArray (nextGroupUuid));
|
||||
|
||||
// Create Group Activity
|
||||
PwGroup nextGroup = App.Kp2a.GetDb ().Groups[nextGroupPwUuid];
|
||||
PwGroup nextGroup = _db.Groups[nextGroupPwUuid];
|
||||
GroupActivity.Launch (groupBaseActivity, nextGroup, this);
|
||||
}
|
||||
return;
|
||||
@@ -968,12 +972,9 @@ namespace keepass2android
|
||||
|
||||
public class NavigateToFolder: NavigateAndLaunchTask {
|
||||
|
||||
public NavigateToFolder()
|
||||
{
|
||||
}
|
||||
|
||||
public NavigateToFolder(PwGroup groups, bool toastEnable = false)
|
||||
: base(groups, new NullTask(), toastEnable)
|
||||
public NavigateToFolder(Database db, PwGroup groups, bool toastEnable = false)
|
||||
: base(db, groups, new NullTask(), toastEnable)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -981,14 +982,9 @@ namespace keepass2android
|
||||
|
||||
public class NavigateToFolderAndLaunchMoveElementTask: NavigateAndLaunchTask {
|
||||
|
||||
public NavigateToFolderAndLaunchMoveElementTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public NavigateToFolderAndLaunchMoveElementTask(PwGroup groups, List<PwUuid> uuids, bool toastEnable = false)
|
||||
:base(groups, new MoveElementsTask() { Uuids = uuids }, toastEnable) {
|
||||
public NavigateToFolderAndLaunchMoveElementTask(Database db, PwGroup groups, List<PwUuid> uuids, bool toastEnable = false)
|
||||
:base(db, groups, new MoveElementsTask() { Uuids = uuids }, toastEnable) {
|
||||
}
|
||||
|
||||
public override void Setup(Bundle b) {
|
||||
|
@@ -17,10 +17,10 @@ namespace keepass2android
|
||||
switch (intent.Action)
|
||||
{
|
||||
case Intents.LockDatabase:
|
||||
App.Kp2a.LockDatabase();
|
||||
App.Kp2a.Lock();
|
||||
break;
|
||||
case Intents.CloseDatabase:
|
||||
App.Kp2a.LockDatabase(false /*no quick unlock*/);
|
||||
App.Kp2a.Lock(false /*no quick unlock*/);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Database;
|
||||
@@ -140,7 +141,6 @@ namespace keepass2android
|
||||
intent.PutExtra(SelectStorageLocationActivity.ExtraKeyWritableRequirements, (int) SelectStorageLocationActivity.WritableRequirements.WriteDesired);
|
||||
intent.PutExtra(FileStorageSetupDefs.ExtraIsForSave, false);
|
||||
StartActivityForResult(intent, RequestCodeSelectIoc);
|
||||
|
||||
};
|
||||
openFileButton.Click += openFileButtonClick;
|
||||
|
||||
@@ -151,7 +151,9 @@ namespace keepass2android
|
||||
//ShowFilenameDialog(false, true, true, Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path), "", Intents.RequestCodeFileBrowseForCreate)
|
||||
Intent i = new Intent(this, typeof (CreateDatabaseActivity));
|
||||
this.AppTask.ToIntent(i);
|
||||
StartActivityForResult(i, 0);
|
||||
i.SetFlags(ActivityFlags.ForwardResult);
|
||||
StartActivity(i);
|
||||
Finish();
|
||||
};
|
||||
createNewButton.Click += createNewButtonClick;
|
||||
|
||||
@@ -460,28 +462,22 @@ namespace keepass2android
|
||||
base.OnStart();
|
||||
Kp2aLog.Log("FileSelect.OnStart");
|
||||
|
||||
var db = App.Kp2a.GetDb();
|
||||
if (db != null)
|
||||
|
||||
//if no database is loaded: load the most recent database
|
||||
if ( (Intent.GetBooleanExtra(NoForwardToPasswordActivity, false)==false) && _dbHelper.HasRecentFiles() && !App.Kp2a.OpenDatabases.Any())
|
||||
{
|
||||
LaunchPasswordActivityForIoc(db.Ioc);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if no database is loaded: load the most recent database
|
||||
if ( (Intent.GetBooleanExtra(NoForwardToPasswordActivity, false)==false) && _dbHelper.HasRecentFiles())
|
||||
ICursor filesCursor = _dbHelper.FetchAllFiles();
|
||||
StartManagingCursor(filesCursor);
|
||||
filesCursor.MoveToFirst();
|
||||
IOConnectionInfo ioc = _dbHelper.CursorToIoc(filesCursor);
|
||||
if (App.Kp2a.GetFileStorage(ioc).RequiresSetup(ioc) == false)
|
||||
{
|
||||
ICursor filesCursor = _dbHelper.FetchAllFiles();
|
||||
StartManagingCursor(filesCursor);
|
||||
filesCursor.MoveToFirst();
|
||||
IOConnectionInfo ioc = _dbHelper.CursorToIoc(filesCursor);
|
||||
if (App.Kp2a.GetFileStorage(ioc).RequiresSetup(ioc) == false)
|
||||
{
|
||||
LaunchPasswordActivityForIoc(ioc);
|
||||
}
|
||||
LaunchPasswordActivityForIoc(ioc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||
base.OnCreateOptionsMenu(menu);
|
||||
|
@@ -1885,6 +1885,9 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_storage_nextcloud.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\open_db_selection.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
|
||||
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
|
||||
|
@@ -47,8 +47,9 @@ namespace keepass2android.search
|
||||
private const string GetIconPathQuery = "get_icon";
|
||||
private const string IconIdParameter = "IconId";
|
||||
private const string CustomIconUuidParameter = "CustomIconUuid";
|
||||
private const string DatabaseIndexParameter = "DatabaseIndex";
|
||||
|
||||
private static UriMatcher UriMatcher = BuildUriMatcher();
|
||||
private static UriMatcher UriMatcher = BuildUriMatcher();
|
||||
|
||||
static UriMatcher BuildUriMatcher()
|
||||
{
|
||||
@@ -78,9 +79,24 @@ namespace keepass2android.search
|
||||
{
|
||||
try
|
||||
{
|
||||
var resultsContexts = new Dictionary<PwUuid, KeyValuePair<string, string>>();
|
||||
var result = App.Kp2a.GetDb().Search(new SearchParameters { SearchString = searchString }, resultsContexts );
|
||||
return new GroupCursor(result, resultsContexts);
|
||||
List<EntryListCursor.EntryWithContext> entriesWithContext = new List<EntryListCursor.EntryWithContext>();
|
||||
int dbIndex = 0;
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
var resultsContexts = new Dictionary<PwUuid, KeyValuePair<string, string>>();
|
||||
PwGroup group = db.Search(new SearchParameters { SearchString = searchString }, resultsContexts);
|
||||
|
||||
foreach (var entry in group.Entries)
|
||||
{
|
||||
KeyValuePair<string, string> context;
|
||||
resultsContexts.TryGetValue(entry.Uuid, out context);
|
||||
entriesWithContext.Add(new EntryListCursor.EntryWithContext(entry, context, dbIndex));
|
||||
}
|
||||
dbIndex++;
|
||||
|
||||
}
|
||||
|
||||
return new EntryListCursor(entriesWithContext);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -116,8 +132,12 @@ namespace keepass2android.search
|
||||
case UriMatches.GetIcon:
|
||||
var iconId = (PwIcon)Enum.Parse(typeof(PwIcon), uri.GetQueryParameter(IconIdParameter));
|
||||
var customIconUuid = new PwUuid(MemUtil.HexStringToByteArray(uri.GetQueryParameter(CustomIconUuidParameter)));
|
||||
int databaseIndex = int.Parse(uri.GetQueryParameter(DatabaseIndexParameter));
|
||||
List<Database> databases = App.Kp2a.OpenDatabases.ToList();
|
||||
Database database = databases[databaseIndex];
|
||||
|
||||
var iconDrawable = App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(App.Context, App.Kp2a.GetDb().KpDatabase, iconId, customIconUuid, false) as BitmapDrawable;
|
||||
|
||||
var iconDrawable = database.DrawableFactory.GetIconDrawable(App.Context, database.KpDatabase, iconId, customIconUuid, false) as BitmapDrawable;
|
||||
if (iconDrawable?.Bitmap != null)
|
||||
|
||||
{
|
||||
@@ -186,29 +206,41 @@ namespace keepass2android.search
|
||||
#endregion
|
||||
|
||||
|
||||
private class GroupCursor : AbstractCursor
|
||||
private class EntryListCursor : AbstractCursor
|
||||
{
|
||||
private static readonly string[] ColumnNames = new[] { Android.Provider.BaseColumns.Id,
|
||||
private readonly List<EntryWithContext> _entriesWithContexts;
|
||||
|
||||
private static readonly string[] ColumnNames = new[] { Android.Provider.BaseColumns.Id,
|
||||
SearchManager.SuggestColumnText1,
|
||||
SearchManager.SuggestColumnText2,
|
||||
SearchManager.SuggestColumnIcon1,
|
||||
SearchManager.SuggestColumnIntentDataId,
|
||||
};
|
||||
|
||||
private readonly PwGroup mGroup;
|
||||
private readonly IDictionary<PwUuid, KeyValuePair<string, string>> mResultContexts;
|
||||
|
||||
public GroupCursor(PwGroup group, IDictionary<PwUuid, KeyValuePair<string, string>> resultContexts)
|
||||
|
||||
public struct EntryWithContext
|
||||
{
|
||||
public readonly PwEntry entry;
|
||||
public readonly KeyValuePair<string, string> resultContext;
|
||||
public readonly int DatabaseIndex;
|
||||
|
||||
public EntryWithContext(PwEntry entry, KeyValuePair<string, string> mResultContext, int databaseIndex)
|
||||
{
|
||||
this.entry = entry;
|
||||
this.resultContext = mResultContext;
|
||||
DatabaseIndex = databaseIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public EntryListCursor(List<EntryWithContext> entriesWithContexts)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!group.Groups.Any(), "Expecting a flat list of groups");
|
||||
|
||||
mGroup = group;
|
||||
mResultContexts = resultContexts;
|
||||
_entriesWithContexts = entriesWithContexts;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get { return (int)Math.Min(mGroup.GetEntriesCount(false), int.MaxValue); }
|
||||
get { return _entriesWithContexts.Count; }
|
||||
}
|
||||
|
||||
public override string[] GetColumnNames()
|
||||
@@ -231,7 +263,10 @@ namespace keepass2android.search
|
||||
{
|
||||
get
|
||||
{
|
||||
return mGroup.Entries.GetAt((uint)MPos);
|
||||
if (MPos < _entriesWithContexts.Count)
|
||||
return _entriesWithContexts[MPos].entry;
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,12 +290,9 @@ namespace keepass2android.search
|
||||
case 1: // SuggestColumnText1
|
||||
return CurrentEntry.Strings.ReadSafe(PwDefs.TitleField);
|
||||
case 2: // SuggestColumnText2
|
||||
KeyValuePair<string, string> context;
|
||||
if (mResultContexts.TryGetValue(CurrentEntry.Uuid, out context))
|
||||
{
|
||||
return Internationalise(context);
|
||||
}
|
||||
return null;
|
||||
if (MPos < _entriesWithContexts.Count)
|
||||
return Internationalise(_entriesWithContexts[MPos].resultContext);
|
||||
return "";
|
||||
case 3: // SuggestColumnIcon1
|
||||
var builder = new Android.Net.Uri.Builder();
|
||||
builder.Scheme(ContentResolver.SchemeContent);
|
||||
@@ -268,7 +300,8 @@ namespace keepass2android.search
|
||||
builder.Path(GetIconPathQuery);
|
||||
builder.AppendQueryParameter(IconIdParameter, CurrentEntry.IconId.ToString());
|
||||
builder.AppendQueryParameter(CustomIconUuidParameter, CurrentEntry.CustomIconUuid.ToHexString());
|
||||
return builder.Build().ToString();
|
||||
builder.AppendQueryParameter(DatabaseIndexParameter, _entriesWithContexts[MPos].DatabaseIndex.ToString());
|
||||
return builder.Build().ToString();
|
||||
case 4: // SuggestColumnIntentDataId
|
||||
return CurrentEntry.Uuid.ToHexString();
|
||||
default:
|
||||
|
@@ -56,15 +56,10 @@ namespace keepass2android.search
|
||||
ProcessIntent(Intent);
|
||||
}
|
||||
|
||||
protected override bool AddEntryEnabled
|
||||
public override bool EntriesBelongToCurrentDatabaseOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
protected override bool AddGroupEnabled
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void OnNewIntent(Intent intent)
|
||||
@@ -84,7 +79,7 @@ namespace keepass2android.search
|
||||
{
|
||||
var entryIntent = new Intent(this, typeof(EntryActivity));
|
||||
entryIntent.PutExtra(EntryActivity.KeyEntry, intent.Data.LastPathSegment);
|
||||
entryIntent.AddFlags(ActivityFlags.ForwardResult);
|
||||
entryIntent.AddFlags(ActivityFlags.ForwardResult);
|
||||
Finish(); // Close this activity so that the entry activity is navigated to from the main activity, not this one.
|
||||
StartActivity(entryIntent);
|
||||
}
|
||||
@@ -97,9 +92,22 @@ namespace keepass2android.search
|
||||
|
||||
private void Query (SearchParameters searchParams)
|
||||
{
|
||||
try {
|
||||
Group = App.Kp2a.GetDb().Search (searchParams, null);
|
||||
} catch (Exception e) {
|
||||
Group = null;
|
||||
try {
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
PwGroup resultsForThisDb = db.Search(searchParams, null);
|
||||
if (Group == null)
|
||||
Group = resultsForThisDb;
|
||||
else
|
||||
{
|
||||
foreach (var entry in resultsForThisDb.Entries)
|
||||
{
|
||||
Group.AddEntry(entry, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
Toast.MakeText(this,e.Message, ToastLength.Long).Show();
|
||||
Finish();
|
||||
|
@@ -35,6 +35,7 @@ using KeePassLib;
|
||||
using KeePassLib.Utility;
|
||||
using Android.Views.InputMethods;
|
||||
using KeePass.Util.Spr;
|
||||
using KeePassLib.Serialization;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -283,7 +284,7 @@ namespace keepass2android
|
||||
if ((intent.Action == Intents.ShowNotification) || (intent.Action == Intents.UpdateKeyboard))
|
||||
{
|
||||
String uuidBytes = intent.GetStringExtra(EntryActivity.KeyEntry);
|
||||
String searchUrl = intent.GetStringExtra(SearchUrlTask.UrlToSearchKey);
|
||||
String searchUrl = intent.GetStringExtra(SearchUrlTask.UrlToSearchKey);
|
||||
|
||||
PwUuid entryId = PwUuid.Zero;
|
||||
if (uuidBytes != null)
|
||||
@@ -292,19 +293,21 @@ namespace keepass2android
|
||||
PwEntryOutput entry;
|
||||
try
|
||||
{
|
||||
if ((App.Kp2a.GetDb().LastOpenedEntry != null)
|
||||
&& (entryId.Equals(App.Kp2a.GetDb().LastOpenedEntry.Uuid)))
|
||||
if ((App.Kp2a.LastOpenedEntry != null)
|
||||
&& (entryId.Equals(App.Kp2a.LastOpenedEntry.Uuid)))
|
||||
{
|
||||
entry = App.Kp2a.GetDb().LastOpenedEntry;
|
||||
entry = App.Kp2a.LastOpenedEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = new PwEntryOutput(App.Kp2a.GetDb().Entries[entryId], App.Kp2a.GetDb().KpDatabase);
|
||||
Database entryDb = App.Kp2a.FindDatabaseForEntryId(entryId);
|
||||
entry = new PwEntryOutput(entryDb.Entries[entryId], entryDb);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Kp2aLog.LogUnexpectedError(e);
|
||||
//seems like restarting the service happened after closing the DB
|
||||
StopSelf();
|
||||
return StartCommandResult.NotSticky;
|
||||
@@ -400,9 +403,10 @@ namespace keepass2android
|
||||
var hadKeyboardData = ClearNotifications();
|
||||
|
||||
String entryName = entry.OutputStrings.ReadSafe(PwDefs.TitleField);
|
||||
Database db = App.Kp2a.FindDatabaseForEntryId(entry.Uuid);
|
||||
|
||||
var bmp = Util.DrawableToBitmap(App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(this,
|
||||
App.Kp2a.GetDb().KpDatabase, entry.Entry.IconId, entry.Entry.CustomIconUuid, false));
|
||||
var bmp = Util.DrawableToBitmap(db.DrawableFactory.GetIconDrawable(this,
|
||||
db.KpDatabase, entry.Entry.IconId, entry.Entry.CustomIconUuid, false));
|
||||
|
||||
|
||||
if (!(((entry.Entry.CustomIconUuid != null) && (!entry.Entry.CustomIconUuid.Equals(PwUuid.Zero))))
|
||||
@@ -807,7 +811,7 @@ namespace keepass2android
|
||||
|
||||
//check if we have a last opened entry
|
||||
//this should always be non-null, but if the OS has killed the app, it might occur.
|
||||
if (App.Kp2a.GetDb().LastOpenedEntry == null)
|
||||
if (App.Kp2a.LastOpenedEntry == null)
|
||||
{
|
||||
Intent i = new Intent(context, typeof(AppKilledInfo));
|
||||
i.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask);
|
||||
@@ -817,7 +821,7 @@ namespace keepass2android
|
||||
|
||||
if (action.Equals(Intents.CopyUsername))
|
||||
{
|
||||
String username = App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.UserNameField);
|
||||
String username = App.Kp2a.LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.UserNameField);
|
||||
if (username.Length > 0)
|
||||
{
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(context, username);
|
||||
@@ -826,7 +830,7 @@ namespace keepass2android
|
||||
}
|
||||
else if (action.Equals(Intents.CopyPassword))
|
||||
{
|
||||
String password = App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.PasswordField);
|
||||
String password = App.Kp2a.LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.PasswordField);
|
||||
if (password.Length > 0)
|
||||
{
|
||||
CopyToClipboardService.CopyValueToClipboardWithTimeout(context, password);
|
||||
|
@@ -28,7 +28,7 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
{
|
||||
//launch FileSelectActivity (which is root of the stack (exception: we're even below!)) with the appropriate task.
|
||||
//will return the results later
|
||||
Intent i = new Intent(this, typeof(FileSelectActivity));
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new SearchUrlTask() { UrlToSearchFor = requestedUrl, ShowUserNotifications = false, AutoReturnFromQuery = autoReturnFromQuery };
|
||||
task.ToIntent(i);
|
||||
@@ -39,9 +39,9 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
|
||||
protected override FilledAutofillFieldCollection GetDataset(Intent data)
|
||||
{
|
||||
if (App.Kp2a.GetDb()==null || (App.Kp2a.QuickLocked))
|
||||
if (App.Kp2a.CurrentDb==null || (App.Kp2a.QuickLocked))
|
||||
return null;
|
||||
var entryOutput = App.Kp2a.GetDb().LastOpenedEntry;
|
||||
var entryOutput = App.Kp2a.LastOpenedEntry;
|
||||
|
||||
return GetFilledAutofillFieldCollectionFromEntry(entryOutput, this);
|
||||
}
|
||||
|
@@ -33,9 +33,9 @@ namespace keepass2android.services
|
||||
|
||||
protected override FilledAutofillFieldCollection GetSuggestedEntry(string query)
|
||||
{
|
||||
if (App.Kp2a.GetDb()?.LastOpenedEntry?.SearchUrl == query)
|
||||
if (App.Kp2a.LastOpenedEntry?.SearchUrl == query)
|
||||
return ChooseForAutofillActivity.GetFilledAutofillFieldCollectionFromEntry(
|
||||
App.Kp2a.GetDb()?.LastOpenedEntry, this);
|
||||
App.Kp2a.LastOpenedEntry, this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace keepass2android.services
|
||||
{
|
||||
|
||||
|
||||
var intent = new Intent(this, typeof(FileSelectActivity));
|
||||
var intent = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
|
||||
Dictionary<string, string> outputFields = new Dictionary<string, string>();
|
||||
foreach (var p in parser.ClientFormData.HintMap)
|
||||
|
@@ -26,7 +26,7 @@ namespace keepass2android.services
|
||||
|
||||
public Intent GetRestartAppIntent(Context context)
|
||||
{
|
||||
var intent = new Intent(context, typeof(FileSelectActivity));
|
||||
var intent = new Intent(context, typeof(SelectCurrentDbActivity));
|
||||
intent.AddFlags(ActivityFlags.ForwardResult);
|
||||
return intent;
|
||||
}
|
||||
|
@@ -97,7 +97,7 @@ namespace keepass2android
|
||||
Kp2aLog.Log("OngoingNotificationsService.OnTaskRemoved: " + rootIntent.Action);
|
||||
|
||||
// If the user has closed the task (probably by swiping it out of the recent apps list) then lock the database
|
||||
App.Kp2a.LockDatabase();
|
||||
App.Kp2a.Lock();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
@@ -111,7 +111,7 @@ namespace keepass2android
|
||||
// If the service is killed, then lock the database immediately
|
||||
if (App.Kp2a.DatabaseIsUnlocked)
|
||||
{
|
||||
App.Kp2a.LockDatabase(false);
|
||||
App.Kp2a.Lock(false);
|
||||
}
|
||||
|
||||
UnregisterReceiver(_screenOffReceiver);
|
||||
@@ -228,16 +228,22 @@ namespace keepass2android
|
||||
|
||||
private static string GetDatabaseName()
|
||||
{
|
||||
string displayString = "";
|
||||
foreach (Database db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
var kpDatabase = db.KpDatabase;
|
||||
var dbname = kpDatabase.Name;
|
||||
if (String.IsNullOrEmpty(dbname))
|
||||
{
|
||||
//todo: if paranoid ("don't remember recent files") return "***"
|
||||
dbname = App.Kp2a.GetFileStorage(kpDatabase.IOConnectionInfo).GetFilenameWithoutPathAndExt(kpDatabase.IOConnectionInfo);
|
||||
}
|
||||
if (displayString != "")
|
||||
displayString = displayString + ", ";
|
||||
displayString += dbname;
|
||||
}
|
||||
|
||||
var db = App.Kp2a.GetDb().KpDatabase;
|
||||
var name = db.Name;
|
||||
if (String.IsNullOrEmpty(name))
|
||||
{
|
||||
//todo: if paranoid ("don't remember recent files") return "***"
|
||||
name = App.Kp2a.GetFileStorage(db.IOConnectionInfo).GetFilenameWithoutPathAndExt(db.IOConnectionInfo);
|
||||
}
|
||||
|
||||
return name;
|
||||
return displayString;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@@ -18,8 +18,8 @@ namespace keepass2android.settings
|
||||
{
|
||||
get
|
||||
{
|
||||
var kdfparams = App.Kp2a.GetDb().KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.GetDb().KpDatabase.KdfParameters.KdfUuid);
|
||||
var kdfparams = App.Kp2a.CurrentDb.KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.CurrentDb.KpDatabase.KdfParameters.KdfUuid);
|
||||
if (!(kdf is Argon2Kdf))
|
||||
{
|
||||
new Argon2Kdf().GetDefaultParameters();
|
||||
@@ -29,7 +29,7 @@ namespace keepass2android.settings
|
||||
}
|
||||
set
|
||||
{
|
||||
App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamIterations, value);
|
||||
App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamIterations, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,8 @@ namespace keepass2android.settings
|
||||
{
|
||||
get
|
||||
{
|
||||
var kdfparams = App.Kp2a.GetDb().KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.GetDb().KpDatabase.KdfParameters.KdfUuid);
|
||||
var kdfparams = App.Kp2a.CurrentDb.KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.CurrentDb.KpDatabase.KdfParameters.KdfUuid);
|
||||
if (!(kdf is Argon2Kdf))
|
||||
{
|
||||
new Argon2Kdf().GetDefaultParameters();
|
||||
@@ -61,7 +61,7 @@ namespace keepass2android.settings
|
||||
}
|
||||
set
|
||||
{
|
||||
App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt32(Argon2Kdf.ParamParallelism, (uint) value);
|
||||
App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt32(Argon2Kdf.ParamParallelism, (uint) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,8 +82,8 @@ namespace keepass2android.settings
|
||||
{
|
||||
get
|
||||
{
|
||||
var kdfparams = App.Kp2a.GetDb().KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.GetDb().KpDatabase.KdfParameters.KdfUuid);
|
||||
var kdfparams = App.Kp2a.CurrentDb.KpDatabase.KdfParameters;
|
||||
var kdf = KdfPool.Get(App.Kp2a.CurrentDb.KpDatabase.KdfParameters.KdfUuid);
|
||||
if (!(kdf is Argon2Kdf))
|
||||
{
|
||||
new Argon2Kdf().GetDefaultParameters();
|
||||
@@ -93,7 +93,7 @@ namespace keepass2android.settings
|
||||
}
|
||||
set
|
||||
{
|
||||
App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamMemory, value);
|
||||
App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamMemory, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -423,7 +423,7 @@ namespace keepass2android
|
||||
|
||||
FindPreference(GetString(Resource.String.design_key)).PreferenceChange += (sender, args) => Activity.Recreate();
|
||||
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
if (db != null)
|
||||
{
|
||||
ListPreference kdfPref = (ListPreference) FindPreference(GetString(Resource.String.kdf_key));
|
||||
@@ -457,7 +457,7 @@ namespace keepass2android
|
||||
algorithmPref.SetValueIndex(algoValues.Select((v, i) => new { kdf = v, index = i }).First(el => el.kdf == db.KpDatabase.DataCipherUuid.ToHexString()).index);
|
||||
algorithmPref.PreferenceChange += AlgorithmPrefChange;
|
||||
algorithmPref.Summary =
|
||||
CipherPool.GlobalPool.GetCipher(App.Kp2a.GetDb().KpDatabase.DataCipherUuid).DisplayName;
|
||||
CipherPool.GlobalPool.GetCipher(App.Kp2a.CurrentDb.KpDatabase.DataCipherUuid).DisplayName;
|
||||
UpdateImportDbPref();
|
||||
UpdateImportKeyfilePref();
|
||||
}
|
||||
@@ -504,8 +504,8 @@ namespace keepass2android
|
||||
|
||||
FindPreference("IconSetKey").PreferenceChange += (sender, args) =>
|
||||
{
|
||||
if (App.Kp2a.GetDb() != null)
|
||||
App.Kp2a.GetDb().DrawableFactory.Clear();
|
||||
if (App.Kp2a.CurrentDb!= null)
|
||||
App.Kp2a.CurrentDb.DrawableFactory.Clear();
|
||||
|
||||
};
|
||||
|
||||
@@ -565,11 +565,11 @@ namespace keepass2android
|
||||
|
||||
private void AlgorithmPrefChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
|
||||
{
|
||||
var db = App.Kp2a.GetDb();
|
||||
var db = App.Kp2a.CurrentDb;
|
||||
var previousCipher = db.KpDatabase.DataCipherUuid;
|
||||
db.KpDatabase.DataCipherUuid = new PwUuid(MemUtil.HexStringToByteArray((string)preferenceChangeEventArgs.NewValue));
|
||||
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
@@ -586,7 +586,7 @@ namespace keepass2android
|
||||
|
||||
private void UpdateKdfScreen()
|
||||
{
|
||||
var db = App.Kp2a.GetDb();
|
||||
var db = App.Kp2a.CurrentDb;
|
||||
var kdf = KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid);
|
||||
|
||||
var kdfpref = FindPreference(GetString(Resource.String.kdf_key));
|
||||
@@ -624,7 +624,7 @@ namespace keepass2android
|
||||
|
||||
private void OnKdfChange(object sender, Preference.PreferenceChangeEventArgs preferenceChangeEventArgs)
|
||||
{
|
||||
var db = App.Kp2a.GetDb();
|
||||
var db = App.Kp2a.CurrentDb;
|
||||
var previousKdfParams = db.KpDatabase.KdfParameters;
|
||||
Kp2aLog.Log("previous kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString() );
|
||||
db.KpDatabase.KdfParameters =
|
||||
@@ -634,7 +634,7 @@ namespace keepass2android
|
||||
|
||||
Kp2aLog.Log("--new kdf: " + KdfPool.Get(db.KpDatabase.KdfParameters.KdfUuid) + " " + db.KpDatabase.KdfParameters.KdfUuid.ToHexString());
|
||||
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
@@ -669,7 +669,7 @@ namespace keepass2android
|
||||
private void PrepareTemplates(Database db)
|
||||
{
|
||||
Preference pref = FindPreference("AddTemplates_pref_key");
|
||||
if ((!db.DatabaseFormat.SupportsTemplates) || (AddTemplateEntries.ContainsAllTemplates(App.Kp2a)))
|
||||
if ((!db.DatabaseFormat.SupportsTemplates) || (AddTemplateEntries.ContainsAllTemplates(App.Kp2a.CurrentDb)))
|
||||
{
|
||||
pref.Enabled = false;
|
||||
}
|
||||
@@ -692,7 +692,7 @@ namespace keepass2android
|
||||
private void PrepareMasterPassword()
|
||||
{
|
||||
Preference changeMaster = FindPreference(GetString(Resource.String.master_pwd_key));
|
||||
if (App.Kp2a.GetDb().CanWrite)
|
||||
if (App.Kp2a.CurrentDb.CanWrite)
|
||||
{
|
||||
changeMaster.Enabled = true;
|
||||
changeMaster.PreferenceClick += delegate { new SetPasswordDialog(Activity).Show(); };
|
||||
@@ -717,7 +717,7 @@ namespace keepass2android
|
||||
String previousName = db.KpDatabase.Name;
|
||||
db.KpDatabase.Name = e.NewValue.ToString();
|
||||
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
@@ -755,7 +755,7 @@ namespace keepass2android
|
||||
String previousUsername = db.KpDatabase.DefaultUserName;
|
||||
db.KpDatabase.DefaultUserName = e.NewValue.ToString();
|
||||
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
SaveDb save = new SaveDb(Activity, App.Kp2a, App.Kp2a.CurrentDb, new ActionOnFinish(Activity, (success, message, activity) =>
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
@@ -791,8 +791,8 @@ namespace keepass2android
|
||||
private void OnUseOfflineCacheChanged(object sender, Preference.PreferenceChangeEventArgs e)
|
||||
{
|
||||
//ensure the user gets a matching database
|
||||
if (App.Kp2a.GetDb() != null && !App.Kp2a.GetDb().Ioc.IsLocalFile())
|
||||
App.Kp2a.LockDatabase(false);
|
||||
if (App.Kp2a.CurrentDb!= null && !App.Kp2a.CurrentDb.Ioc.IsLocalFile())
|
||||
App.Kp2a.LockSingleDatabase(App.Kp2a.CurrentDb, false);
|
||||
|
||||
if (!(bool)e.NewValue)
|
||||
{
|
||||
@@ -842,7 +842,7 @@ namespace keepass2android
|
||||
importDb.Enabled = false;
|
||||
return;
|
||||
}
|
||||
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
||||
CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
||||
if (masterKey.ContainsType(typeof(KcpKeyFile)))
|
||||
{
|
||||
IOConnectionInfo iocKeyfile = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
|
||||
@@ -871,12 +871,12 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
CompositeKey masterKey = App.Kp2a.GetDb().KpDatabase.MasterKey;
|
||||
CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
||||
var sourceIoc = ((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
|
||||
var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
|
||||
((KcpKeyFile)masterKey.GetUserKey(typeof(KcpKeyFile))).ResetIoc(newIoc);
|
||||
var keyfileString = IOConnectionInfo.SerializeToString(newIoc);
|
||||
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.GetDb().Ioc, keyfileString);
|
||||
App.Kp2a.StoreOpenedFileAsRecent(App.Kp2a.CurrentDb.Ioc, keyfileString);
|
||||
return () =>
|
||||
{
|
||||
UpdateImportKeyfilePref();
|
||||
@@ -914,7 +914,7 @@ namespace keepass2android
|
||||
//Import db/key file preferences:
|
||||
Preference importDb = FindPreference("import_db_prefs");
|
||||
bool isLocalOrContent =
|
||||
App.Kp2a.GetDb().Ioc.IsLocalFile() || App.Kp2a.GetDb().Ioc.Path.StartsWith("content://");
|
||||
App.Kp2a.CurrentDb.Ioc.IsLocalFile() || App.Kp2a.CurrentDb.Ioc.Path.StartsWith("content://");
|
||||
if (!isLocalOrContent)
|
||||
{
|
||||
importDb.Summary = GetString(Resource.String.OnlyAvailableForLocalFiles);
|
||||
@@ -922,7 +922,7 @@ namespace keepass2android
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IoUtil.IsInInternalDirectory(App.Kp2a.GetDb().Ioc.Path, Activity))
|
||||
if (IoUtil.IsInInternalDirectory(App.Kp2a.CurrentDb.Ioc.Path, Activity))
|
||||
{
|
||||
importDb.Summary = GetString(Resource.String.FileIsInInternalDirectory);
|
||||
importDb.Enabled = false;
|
||||
@@ -941,7 +941,7 @@ namespace keepass2android
|
||||
{
|
||||
try
|
||||
{
|
||||
var sourceIoc = App.Kp2a.GetDb().Ioc;
|
||||
var sourceIoc = App.Kp2a.CurrentDb.Ioc;
|
||||
var newIoc = IoUtil.ImportFileToInternalDirectory(sourceIoc, Activity, App.Kp2a);
|
||||
return () =>
|
||||
{
|
||||
@@ -949,7 +949,12 @@ namespace keepass2android
|
||||
builder
|
||||
.SetMessage(Resource.String.DatabaseFileMoved);
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, (sender, args) =>
|
||||
PasswordActivity.Launch(Activity, newIoc, new NullTask(), App.Kp2a.GetDb().KpDatabase.MasterKey));
|
||||
{
|
||||
var key = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
|
||||
App.Kp2a.CloseDatabase(App.Kp2a.CurrentDb);
|
||||
PasswordActivity.Launch(Activity, newIoc, new NullTask(), key);
|
||||
|
||||
});
|
||||
builder.Show();
|
||||
|
||||
};
|
||||
|
@@ -77,7 +77,7 @@ namespace keepass2android.settings
|
||||
paramValue = 1;
|
||||
}
|
||||
|
||||
Database db = App.Kp2a.GetDb();
|
||||
Database db = App.Kp2a.CurrentDb;
|
||||
|
||||
ulong oldValue = ParamValue;
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace keepass2android.settings
|
||||
ParamValue = paramValue;
|
||||
|
||||
Handler handler = new Handler();
|
||||
SaveDb save = new SaveDb((Activity)Context, App.Kp2a, new KdfNumberParamPreference.AfterSave((Activity)Context, handler, oldValue, this));
|
||||
SaveDb save = new SaveDb((Activity)Context, App.Kp2a, App.Kp2a.CurrentDb, new KdfNumberParamPreference.AfterSave((Activity)Context, handler, oldValue, this));
|
||||
ProgressTask pt = new ProgressTask(App.Kp2a, (Activity)Context, save);
|
||||
pt.Run();
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace keepass2android.settings
|
||||
} else {
|
||||
DisplayMessage(_ctx);
|
||||
|
||||
App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, _oldRounds);
|
||||
App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, _oldRounds);
|
||||
}
|
||||
|
||||
base.Run();
|
||||
@@ -140,18 +140,18 @@ namespace keepass2android.settings
|
||||
get
|
||||
{
|
||||
AesKdf kdf = new AesKdf();
|
||||
if (!kdf.Uuid.Equals(App.Kp2a.GetDb().KpDatabase.KdfParameters.KdfUuid))
|
||||
if (!kdf.Uuid.Equals(App.Kp2a.CurrentDb.KpDatabase.KdfParameters.KdfUuid))
|
||||
return (uint) PwDefs.DefaultKeyEncryptionRounds;
|
||||
else
|
||||
{
|
||||
ulong uRounds = App.Kp2a.GetDb().KpDatabase.KdfParameters.GetUInt64(
|
||||
ulong uRounds = App.Kp2a.CurrentDb.KpDatabase.KdfParameters.GetUInt64(
|
||||
AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
|
||||
uRounds = Math.Min(uRounds, 0xFFFFFFFEUL);
|
||||
|
||||
return (uint) uRounds;
|
||||
}
|
||||
}
|
||||
set { App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, value); }
|
||||
set { App.Kp2a.CurrentDb.KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, value); }
|
||||
}
|
||||
|
||||
public RoundsPreference(Context context, IAttributeSet attrs):base(context, attrs)
|
||||
|
@@ -83,7 +83,7 @@ namespace keepass2android
|
||||
|
||||
public static void Resume(Activity act)
|
||||
{
|
||||
if ( App.Kp2a.GetDb() != null)
|
||||
if ( App.Kp2a.CurrentDb!= null)
|
||||
{
|
||||
Timeout.Cancel(act);
|
||||
}
|
||||
@@ -92,14 +92,13 @@ namespace keepass2android
|
||||
static bool IocChanged(IOConnectionInfo ioc, IOConnectionInfo other)
|
||||
{
|
||||
if ((ioc == null) || (other == null)) return false;
|
||||
return ioc.GetDisplayName() != other.GetDisplayName();
|
||||
return !ioc.IsSameFileAs(other);
|
||||
}
|
||||
|
||||
public static bool CheckShutdown(Activity act, IOConnectionInfo ioc) {
|
||||
public static bool CheckDbChanged(Activity act, IOConnectionInfo ioc) {
|
||||
if (( !App.Kp2a.DatabaseIsUnlocked )
|
||||
|| (IocChanged(ioc, App.Kp2a.GetDb().Ioc))) //file was changed from ActionSend-Intent
|
||||
|| (IocChanged(ioc, App.Kp2a.CurrentDb.Ioc))) //file was changed from ActionSend-Intent
|
||||
{
|
||||
App.Kp2a.LockDatabase();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@@ -71,8 +71,9 @@ namespace keepass2android.view
|
||||
_textView = (TextView)ev.FindViewById(Resource.Id.entry_text);
|
||||
_textView.TextSize = PrefsUtil.GetListTextSize(groupActivity);
|
||||
|
||||
Database db = App.Kp2a.FindDatabaseForEntryId(pw.Uuid);
|
||||
|
||||
ev.FindViewById(Resource.Id.entry_icon_bkg).Visibility = App.Kp2a.GetDb().DrawableFactory.IsWhiteIconSet ? ViewStates.Visible : ViewStates.Gone;
|
||||
ev.FindViewById(Resource.Id.entry_icon_bkg).Visibility = db.DrawableFactory.IsWhiteIconSet ? ViewStates.Visible : ViewStates.Gone;
|
||||
|
||||
_textviewDetails = (TextView)ev.FindViewById(Resource.Id.entry_text_detail);
|
||||
_textviewDetails.TextSize = PrefsUtil.GetListDetailTextSize(groupActivity);
|
||||
@@ -106,15 +107,16 @@ namespace keepass2android.view
|
||||
ev.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible;
|
||||
ev.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible;
|
||||
|
||||
Database db = App.Kp2a.FindDatabaseForEntryId(_entry.Uuid);
|
||||
|
||||
ImageView iv = (ImageView)ev.FindViewById(Resource.Id.icon);
|
||||
bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now;
|
||||
if (isExpired)
|
||||
{
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Context, App.Kp2a.GetDb().KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
} else
|
||||
{
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Context, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
}
|
||||
|
||||
String title = pw.Strings.ReadSafe(PwDefs.TitleField);
|
||||
@@ -138,7 +140,7 @@ namespace keepass2android.view
|
||||
_textView.SetTextColor(new Color((int)_defaultTextColor));
|
||||
|
||||
String detail = pw.Strings.ReadSafe(PwDefs.UserNameField);
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, App.Kp2a.GetDb().KpDatabase, SprCompileFlags.All));
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, db.KpDatabase, SprCompileFlags.All));
|
||||
|
||||
if ((_showDetail == false) || (String.IsNullOrEmpty(detail)))
|
||||
{
|
||||
|
@@ -63,7 +63,9 @@ namespace keepass2android.view
|
||||
_label = (TextView) gv.FindViewById(Resource.Id.group_label);
|
||||
_label.TextSize = size-8;
|
||||
|
||||
gv.FindViewById(Resource.Id.group_icon_bkg).Visibility = App.Kp2a.GetDb().DrawableFactory.IsWhiteIconSet ? ViewStates.Visible : ViewStates.Gone;
|
||||
Database db = App.Kp2a.FindDatabaseForGroupId(pw.Uuid);
|
||||
|
||||
gv.FindViewById(Resource.Id.group_icon_bkg).Visibility = db.DrawableFactory.IsWhiteIconSet ? ViewStates.Visible : ViewStates.Gone;
|
||||
|
||||
gv.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible;
|
||||
gv.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible;
|
||||
@@ -79,7 +81,8 @@ namespace keepass2android.view
|
||||
_pwGroup = pw;
|
||||
|
||||
ImageView iv = (ImageView) gv.FindViewById(Resource.Id.icon);
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, _groupBaseActivity, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid, true);
|
||||
Database db = App.Kp2a.FindDatabaseForGroupId(pw.Uuid);
|
||||
db.DrawableFactory.AssignDrawableTo(iv, _groupBaseActivity, db.KpDatabase, pw.IconId, pw.CustomIconUuid, true);
|
||||
gv.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible;
|
||||
gv.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible;
|
||||
|
||||
|
Reference in New Issue
Block a user