mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-26 03:02:24 -05:00
Merge remote-tracking branch 'upstream/master'
Conflicts: src/Kp2aBusinessLogic/SearchDbHelper.cs src/keepass2android/Database.cs src/keepass2android/EntryActivity.cs src/keepass2android/EntryEditActivity.cs src/keepass2android/icons/DrawableFactory.cs src/keepass2android/search/SearchResults.cs
This commit is contained in:
commit
f442a04520
2
.gitignore
vendored
2
.gitignore
vendored
@ -26,3 +26,5 @@
|
|||||||
/src/java/KP2ASoftKeyboard/projectzip
|
/src/java/KP2ASoftKeyboard/projectzip
|
||||||
/src/java/KP2ASoftKeyboard/createProjectZip.bat
|
/src/java/KP2ASoftKeyboard/createProjectZip.bat
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
/src/monodroid-unittesting/*.suo
|
||||||
|
138
src/KeePass.sln
138
src/KeePass.sln
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2010
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android", "keepass2android\keepass2android.csproj", "{A6CF8A86-37C1-4197-80FE-519DE2C842F5}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android", "keepass2android\keepass2android.csproj", "{A6CF8A86-37C1-4197-80FE-519DE2C842F5}"
|
||||||
@ -9,6 +9,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kp2akeytransform", "kp2akey
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aKeyboardBinding", "Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj", "{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aKeyboardBinding", "Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj", "{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBusinessLogic\Kp2aBusinessLogic.csproj", "{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDroidUnitTesting", "monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj", "{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aUnitTests", "Kp2aUnitTests\Kp2aUnitTests.csproj", "{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -20,6 +26,9 @@ Global
|
|||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
ReleaseNoNet|Any CPU = ReleaseNoNet|Any CPU
|
ReleaseNoNet|Any CPU = ReleaseNoNet|Any CPU
|
||||||
|
ReleaseNoNet|Mixed Platforms = ReleaseNoNet|Mixed Platforms
|
||||||
|
ReleaseNoNet|Win32 = ReleaseNoNet|Win32
|
||||||
|
ReleaseNoNet|x64 = ReleaseNoNet|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
@ -40,6 +49,34 @@ Global
|
|||||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Mixed Platforms.Deploy.0 = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
|
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
|
||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
@ -58,24 +95,10 @@ Global
|
|||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.Release|x64.Build.0 = Release|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
{A57B3ACE-5634-469A-88C4-858BB409F356}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|Win32.Build.0 = Debug|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.ActiveCfg = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|Win32.Build.0 = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
|
|
||||||
{A6CF8A86-37C1-4197-80FE-519DE2C842F5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
|
|
||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
@ -94,7 +117,73 @@ Global
|
|||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
|
||||||
|
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(MonoDevelopProperties) = preSolution
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
StartupItem = keepass2android\keepass2android.csproj
|
StartupItem = keepass2android\keepass2android.csproj
|
||||||
@ -102,7 +191,7 @@ Global
|
|||||||
$0.DotNetNamingPolicy = $1
|
$0.DotNetNamingPolicy = $1
|
||||||
$1.DirectoryNamespaceAssociation = None
|
$1.DirectoryNamespaceAssociation = None
|
||||||
$1.ResourceNamePolicy = FileFormatDefault
|
$1.ResourceNamePolicy = FileFormatDefault
|
||||||
$0.TextStylePolicy = $2
|
$0.TextStylePolicy = $5
|
||||||
$2.FileWidth = 120
|
$2.FileWidth = 120
|
||||||
$2.TabsToSpaces = False
|
$2.TabsToSpaces = False
|
||||||
$2.inheritsSet = VisualStudio
|
$2.inheritsSet = VisualStudio
|
||||||
@ -127,13 +216,11 @@ Global
|
|||||||
$3.inheritsSet = Mono
|
$3.inheritsSet = Mono
|
||||||
$3.inheritsScope = text/x-csharp
|
$3.inheritsScope = text/x-csharp
|
||||||
$3.scope = text/x-csharp
|
$3.scope = text/x-csharp
|
||||||
$0.TextStylePolicy = $4
|
|
||||||
$4.FileWidth = 120
|
$4.FileWidth = 120
|
||||||
$4.TabsToSpaces = False
|
$4.TabsToSpaces = False
|
||||||
$4.inheritsSet = VisualStudio
|
$4.inheritsSet = VisualStudio
|
||||||
$4.inheritsScope = text/plain
|
$4.inheritsScope = text/plain
|
||||||
$4.scope = text/plain
|
$4.scope = text/plain
|
||||||
$0.TextStylePolicy = $5
|
|
||||||
$5.inheritsSet = null
|
$5.inheritsSet = null
|
||||||
$5.scope = application/xml
|
$5.scope = application/xml
|
||||||
$0.XmlFormattingPolicy = $6
|
$0.XmlFormattingPolicy = $6
|
||||||
@ -144,7 +231,4 @@ Global
|
|||||||
$7.Text = @/*\nThis file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.\n\n Keepass2Android is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n Keepass2Android is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.\n */\n
|
$7.Text = @/*\nThis file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.\n\n Keepass2Android is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 2 of the License, or\n (at your option) any later version.\n\n Keepass2Android is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.\n */\n
|
||||||
$7.IncludeInNewFiles = True
|
$7.IncludeInNewFiles = True
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
17
src/Kp2aBusinessLogic/IDrawableFactory.cs
Normal file
17
src/Kp2aBusinessLogic/IDrawableFactory.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Android.Widget;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using KeePassLib;
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
public interface IDrawableFactory
|
||||||
|
{
|
||||||
|
void AssignDrawableTo (ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId);
|
||||||
|
|
||||||
|
Drawable GetIconDrawable(Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId);
|
||||||
|
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
}
|
||||||
|
}
|
53
src/Kp2aBusinessLogic/IKp2aApp.cs
Normal file
53
src/Kp2aBusinessLogic/IKp2aApp.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using Android.Content;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface through which Activities and the logic layer can access some app specific functionalities and Application static data
|
||||||
|
/// </summary>
|
||||||
|
/// This also contains methods which are UI specific and should be replacable for testing.
|
||||||
|
public interface IKp2aApp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the flag that the database needs to be locked.
|
||||||
|
/// </summary>
|
||||||
|
void SetShutdown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the current database
|
||||||
|
/// </summary>
|
||||||
|
Database GetDb();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tell the app that the file from ioc was opened with keyfile.
|
||||||
|
/// </summary>
|
||||||
|
void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new database and returns it
|
||||||
|
/// </summary>
|
||||||
|
Database CreateNewDatabase();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the user-displayable string identified by stringKey
|
||||||
|
/// </summary>
|
||||||
|
string GetResourceString(UiStringKey stringKey);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the value from the preferences corresponding to key
|
||||||
|
/// </summary>
|
||||||
|
bool GetBooleanPreference(PreferenceKey key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asks the user the question "messageKey" with the options Yes/No/Cancel, calls the handler corresponding to the answer.
|
||||||
|
/// </summary>
|
||||||
|
void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey,
|
||||||
|
EventHandler<DialogClickEventArgs> yesHandler,
|
||||||
|
EventHandler<DialogClickEventArgs> noHandler,
|
||||||
|
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||||
|
Context ctx);
|
||||||
|
}
|
||||||
|
}
|
@ -16,20 +16,12 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
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;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Thrown when there is an error adding the keyfie to the user key
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class KeyFileException : Exception
|
public class KeyFileException : Exception
|
||||||
{
|
{
|
86
src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
Normal file
86
src/Kp2aBusinessLogic/Kp2aBusinessLogic.csproj
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>keepass2android</RootNamespace>
|
||||||
|
<AssemblyName>Kp2aBusinessLogic</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||||
|
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Mono.Android" />
|
||||||
|
<Reference Include="mscorlib" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="PreferenceKey.cs" />
|
||||||
|
<Compile Include="UiStringKey.cs" />
|
||||||
|
<Compile Include="database\Database.cs" />
|
||||||
|
<Compile Include="database\edit\ActionOnFinish.cs" />
|
||||||
|
<Compile Include="database\edit\AddEntry.cs" />
|
||||||
|
<Compile Include="database\edit\AddGroup.cs" />
|
||||||
|
<Compile Include="database\edit\CreateDb.cs" />
|
||||||
|
<Compile Include="database\edit\DeleteEntry.cs" />
|
||||||
|
<Compile Include="database\edit\DeleteGroup.cs" />
|
||||||
|
<Compile Include="database\edit\DeleteRunnable.cs" />
|
||||||
|
<Compile Include="database\edit\FileOnFinish.cs" />
|
||||||
|
<Compile Include="database\edit\LoadDb.cs" />
|
||||||
|
<Compile Include="database\edit\OnFinish.cs" />
|
||||||
|
<Compile Include="database\edit\RunnableOnFinish.cs" />
|
||||||
|
<Compile Include="database\edit\SaveDb.cs" />
|
||||||
|
<Compile Include="database\edit\SetPassword.cs" />
|
||||||
|
<Compile Include="database\edit\UpdateEntry.cs" />
|
||||||
|
<Compile Include="IKp2aApp.cs" />
|
||||||
|
<Compile Include="IDrawableFactory.cs" />
|
||||||
|
<Compile Include="KeyFileException.cs" />
|
||||||
|
<Compile Include="ProgressTask.cs" />
|
||||||
|
<Compile Include="PwGroupEqualityFromIdComparer.cs" />
|
||||||
|
<Compile Include="PwUuidEqualityComparer.cs" />
|
||||||
|
<Compile Include="Resources\Resource.Designer.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="SearchDbHelper.cs" />
|
||||||
|
<Compile Include="UpdateStatus.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||||
|
<Project>{545b4a6b-8bba-4fbe-92fc-4ac060122a54}</Project>
|
||||||
|
<Name>KeePassLib2Android</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
11
src/Kp2aBusinessLogic/PreferenceKey.cs
Normal file
11
src/Kp2aBusinessLogic/PreferenceKey.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Keys which can be used to get a preference setting
|
||||||
|
/// </summary>
|
||||||
|
public enum PreferenceKey
|
||||||
|
{
|
||||||
|
remember_keyfile,
|
||||||
|
UseFileTransactions
|
||||||
|
}
|
||||||
|
}
|
@ -15,68 +15,62 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Java.Lang;
|
using Java.Lang;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class to run a task while a progress dialog is shown
|
||||||
|
/// </summary>
|
||||||
public class ProgressTask {
|
public class ProgressTask {
|
||||||
private Context mCtx;
|
private readonly Handler _handler;
|
||||||
private Handler mHandler;
|
private readonly RunnableOnFinish _task;
|
||||||
private RunnableOnFinish mTask;
|
private readonly ProgressDialog _progressDialog;
|
||||||
private ProgressDialog mPd;
|
private readonly IKp2aApp _app;
|
||||||
|
|
||||||
public ProgressTask(Context ctx, RunnableOnFinish task, int messageId) {
|
public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task, UiStringKey messageKey) {
|
||||||
mCtx = ctx;
|
_task = task;
|
||||||
mTask = task;
|
_handler = new Handler();
|
||||||
mHandler = new Handler();
|
_app = app;
|
||||||
|
|
||||||
// Show process dialog
|
// Show process dialog
|
||||||
mPd = new ProgressDialog(mCtx);
|
_progressDialog = new ProgressDialog(ctx);
|
||||||
mPd.SetTitle(ctx.GetText(Resource.String.progress_title));
|
_progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title));
|
||||||
mPd.SetMessage(ctx.GetText(messageId));
|
_progressDialog.SetMessage(_app.GetResourceString(messageKey));
|
||||||
|
|
||||||
// Set code to run when this is finished
|
// Set code to run when this is finished
|
||||||
mTask.setStatus(new UpdateStatus(ctx, mHandler, mPd));
|
_task.SetStatus(new UpdateStatus(_app, _handler, _progressDialog));
|
||||||
mTask.mFinish = new AfterTask(task.mFinish, mHandler, mPd);
|
_task.OnFinishToRun = new AfterTask(task.OnFinishToRun, _handler, _progressDialog);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void Run() {
|
||||||
// Show process dialog
|
// Show process dialog
|
||||||
mPd.Show();
|
_progressDialog.Show();
|
||||||
|
|
||||||
|
|
||||||
// Start Thread to Run task
|
// Start Thread to Run task
|
||||||
Thread t = new Thread(mTask.run);
|
Thread t = new Thread(_task.Run);
|
||||||
t.Start();
|
t.Start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterTask : OnFinish {
|
private class AfterTask : OnFinish {
|
||||||
|
readonly ProgressDialog _progressDialog;
|
||||||
ProgressDialog mPd;
|
|
||||||
|
|
||||||
public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler)
|
public AfterTask (OnFinish finish, Handler handler, ProgressDialog pd): base(finish, handler)
|
||||||
{
|
{
|
||||||
mPd = pd;
|
_progressDialog = pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
base.run();
|
base.Run();
|
||||||
|
|
||||||
// Remove the progress dialog
|
// Remove the progress dialog
|
||||||
mHandler.Post(delegate() {mPd.Dismiss();});
|
Handler.Post(delegate {_progressDialog.Dismiss();});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
34
src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs
Normal file
34
src/Kp2aBusinessLogic/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Android.App;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Kp2aBusinessLogic")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Kp2aBusinessLogic")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
||||||
|
// Add some common permissions, these can be removed if not needed
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
|
@ -15,21 +15,14 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
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;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// EqualityComparer implementation to compare PwGroups based on their Id
|
||||||
|
/// </summary>
|
||||||
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
|
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
|
||||||
{
|
{
|
||||||
#region IEqualityComparer implementation
|
#region IEqualityComparer implementation
|
@ -15,23 +15,15 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
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;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
class PwUuidEqualityComparer: IEqualityComparer<PwUuid>
|
/// <summary>
|
||||||
|
/// EqualityComparer for PwUuid based on their value (instead of reference)
|
||||||
|
/// </summary>
|
||||||
|
public class PwUuidEqualityComparer: IEqualityComparer<PwUuid>
|
||||||
{
|
{
|
||||||
#region IEqualityComparer implementation
|
#region IEqualityComparer implementation
|
||||||
public bool Equals (PwUuid x, PwUuid y)
|
public bool Equals (PwUuid x, PwUuid y)
|
0
src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
generated
Normal file
0
src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
generated
Normal file
@ -15,44 +15,34 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
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;
|
||||||
using Android.Preferences;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using KeePassLib.Collections;
|
using KeePassLib.Collections;
|
||||||
using KeePassLib.Interfaces;
|
using KeePassLib.Interfaces;
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
using Android.Util;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Helper class providing methods to search a given database for specific things
|
||||||
|
/// </summary>
|
||||||
public class SearchDbHelper
|
public class SearchDbHelper
|
||||||
{
|
{
|
||||||
|
private readonly IKp2aApp _app;
|
||||||
|
|
||||||
private readonly Context mCtx;
|
|
||||||
|
|
||||||
public SearchDbHelper(Context ctx) {
|
public SearchDbHelper(IKp2aApp app) {
|
||||||
mCtx = ctx;
|
_app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PwGroup searchForText (Database database, string str)
|
public PwGroup SearchForText (Database database, string str)
|
||||||
{
|
{
|
||||||
SearchParameters sp = new SearchParameters();
|
SearchParameters sp = new SearchParameters {SearchString = str};
|
||||||
sp.SearchString = str;
|
|
||||||
|
|
||||||
return search(database, sp, null);
|
return Search(database, sp, null);
|
||||||
}
|
}
|
||||||
public PwGroup search(Database database, SearchParameters sp, IDictionary<PwUuid, String> resultContexts)
|
public PwGroup Search(Database database, SearchParameters sp, IDictionary<PwUuid, String> resultContexts)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(sp.RegularExpression) // Validate regular expression
|
if(sp.RegularExpression) // Validate regular expression
|
||||||
@ -60,14 +50,13 @@ namespace keepass2android
|
|||||||
new Regex(sp.SearchString);
|
new Regex(sp.SearchString);
|
||||||
}
|
}
|
||||||
|
|
||||||
string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + sp.SearchString + "\")";
|
string strGroupName = _app.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")";
|
||||||
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
|
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) {IsVirtual = true};
|
||||||
pgResults.IsVirtual = true;
|
|
||||||
|
|
||||||
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
||||||
|
|
||||||
|
|
||||||
database.root.SearchEntries(sp, listResults, resultContexts, new NullStatusLogger());
|
database.Root.SearchEntries(sp, listResults, resultContexts, new NullStatusLogger());
|
||||||
|
|
||||||
|
|
||||||
return pgResults;
|
return pgResults;
|
||||||
@ -76,7 +65,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PwGroup searchForExactUrl (Database database, string url)
|
public PwGroup SearchForExactUrl (Database database, string url)
|
||||||
{
|
{
|
||||||
SearchParameters sp = SearchParameters.None;
|
SearchParameters sp = SearchParameters.None;
|
||||||
sp.SearchInUrls = true;
|
sp.SearchInUrls = true;
|
||||||
@ -87,36 +76,34 @@ namespace keepass2android
|
|||||||
new Regex(sp.SearchString);
|
new Regex(sp.SearchString);
|
||||||
}
|
}
|
||||||
|
|
||||||
string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + sp.SearchString + "\")";
|
string strGroupName = _app.GetResourceString(UiStringKey.search_results) + " (\"" + sp.SearchString + "\")";
|
||||||
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
|
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) {IsVirtual = true};
|
||||||
pgResults.IsVirtual = true;
|
|
||||||
|
|
||||||
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
||||||
|
|
||||||
|
|
||||||
database.root.SearchEntries(sp, listResults, new NullStatusLogger());
|
database.Root.SearchEntries(sp, listResults, new NullStatusLogger());
|
||||||
|
|
||||||
|
|
||||||
return pgResults;
|
return pgResults;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractHost(String url)
|
private static String ExtractHost(String url)
|
||||||
{
|
{
|
||||||
return UrlUtil.GetHost(url.Trim());
|
return UrlUtil.GetHost(url.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
public PwGroup searchForHost(Database database, String url, bool allowSubdomains)
|
public PwGroup SearchForHost(Database database, String url, bool allowSubdomains)
|
||||||
{
|
{
|
||||||
String host = extractHost(url);
|
String host = ExtractHost(url);
|
||||||
string strGroupName = mCtx.GetString(Resource.String.search_results) + " (\"" + host + "\")";
|
string strGroupName = _app.GetResourceString(UiStringKey.search_results) + " (\"" + host + "\")";
|
||||||
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch);
|
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) {IsVirtual = true};
|
||||||
pgResults.IsVirtual = true;
|
|
||||||
if (String.IsNullOrWhiteSpace(host))
|
if (String.IsNullOrWhiteSpace(host))
|
||||||
return pgResults;
|
return pgResults;
|
||||||
foreach (PwEntry entry in database.entries.Values)
|
foreach (PwEntry entry in database.Entries.Values)
|
||||||
{
|
{
|
||||||
String otherHost = extractHost(entry.Strings.ReadSafe(PwDefs.UrlField));
|
String otherHost = ExtractHost(entry.Strings.ReadSafe(PwDefs.UrlField));
|
||||||
if ((allowSubdomains) && (otherHost.StartsWith("www.")))
|
if ((allowSubdomains) && (otherHost.StartsWith("www.")))
|
||||||
otherHost = otherHost.Substring(4); //remove "www."
|
otherHost = otherHost.Substring(4); //remove "www."
|
||||||
if (String.IsNullOrWhiteSpace(otherHost))
|
if (String.IsNullOrWhiteSpace(otherHost))
|
22
src/Kp2aBusinessLogic/UiStringKey.cs
Normal file
22
src/Kp2aBusinessLogic/UiStringKey.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Keys to identify user-displayable strings.
|
||||||
|
/// </summary>
|
||||||
|
/// Do not rename the keys here unless you rename the corresponding keys in the resource file of KP2A.
|
||||||
|
/// The keys are resolved by reflection to the static Resource class. This kind of duplication is necessary
|
||||||
|
/// in order to use the Resource mechanism of Android but still decouple the logic layer from the UI.
|
||||||
|
public enum UiStringKey
|
||||||
|
{
|
||||||
|
AskDeletePermanentlyGroup,
|
||||||
|
progress_title,
|
||||||
|
AskDeletePermanentlyEntry,
|
||||||
|
search_results,
|
||||||
|
AskDeletePermanently_title,
|
||||||
|
saving_database,
|
||||||
|
keyfile_does_not_exist,
|
||||||
|
RecycleBin,
|
||||||
|
progress_create,
|
||||||
|
loading_database
|
||||||
|
}
|
||||||
|
}
|
@ -16,45 +16,40 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib.Interfaces;
|
using KeePassLib.Interfaces;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// StatusLogger implementation which shows the progress in a progress dialog
|
||||||
|
/// </summary>
|
||||||
public class UpdateStatus: IStatusLogger {
|
public class UpdateStatus: IStatusLogger {
|
||||||
private ProgressDialog mPD;
|
private readonly ProgressDialog _progressDialog;
|
||||||
private Context mCtx;
|
readonly IKp2aApp _app;
|
||||||
private Handler mHandler;
|
private readonly Handler _handler;
|
||||||
|
|
||||||
public UpdateStatus() {
|
public UpdateStatus() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UpdateStatus(Context ctx, Handler handler, ProgressDialog pd) {
|
public UpdateStatus(IKp2aApp app, Handler handler, ProgressDialog pd) {
|
||||||
mCtx = ctx;
|
_app = app;
|
||||||
mPD = pd;
|
_progressDialog = pd;
|
||||||
mHandler = handler;
|
_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMessage(int resId) {
|
public void UpdateMessage(UiStringKey stringKey) {
|
||||||
if ( mCtx != null && mPD != null && mHandler != null ) {
|
if ( _app != null && _progressDialog != null && _handler != null ) {
|
||||||
mHandler.Post( () => {mPD.SetMessage(mCtx.GetString(resId));});
|
_handler.Post( () => {_progressDialog.SetMessage(_app.GetResourceString(stringKey));});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMessage (String message)
|
public void UpdateMessage (String message)
|
||||||
{
|
{
|
||||||
if ( mCtx != null && mPD != null && mHandler != null ) {
|
if ( _app!= null && _progressDialog != null && _handler != null ) {
|
||||||
mHandler.Post(() => {mPD.SetMessage(message); } );
|
_handler.Post(() => {_progressDialog.SetMessage(message); } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +72,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
public bool SetText (string strNewText, LogStatusType lsType)
|
public bool SetText (string strNewText, LogStatusType lsType)
|
||||||
{
|
{
|
||||||
updateMessage(strNewText);
|
UpdateMessage(strNewText);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
218
src/Kp2aBusinessLogic/database/Database.cs
Normal file
218
src/Kp2aBusinessLogic/database/Database.cs
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||||
|
|
||||||
|
Keepass2Android is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Keepass2Android is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Android.Content;
|
||||||
|
using KeePassLib;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
|
||||||
|
public class Database {
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
public DateTime LastChangeDate;
|
||||||
|
public SearchDbHelper SearchHelper;
|
||||||
|
|
||||||
|
public IDrawableFactory DrawableFactory;
|
||||||
|
|
||||||
|
readonly IKp2aApp _app;
|
||||||
|
|
||||||
|
public Database(IDrawableFactory drawableFactory, IKp2aApp app)
|
||||||
|
{
|
||||||
|
DrawableFactory = drawableFactory;
|
||||||
|
_app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _loaded;
|
||||||
|
|
||||||
|
private bool _reloadRequested;
|
||||||
|
|
||||||
|
public bool ReloadRequested
|
||||||
|
{
|
||||||
|
get { return _reloadRequested; }
|
||||||
|
set { _reloadRequested = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Loaded {
|
||||||
|
get { return _loaded;}
|
||||||
|
set { _loaded = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Open
|
||||||
|
{
|
||||||
|
get { return Loaded && (!Locked); }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _locked;
|
||||||
|
public bool Locked
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _locked;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_locked = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DidOpenFileChange()
|
||||||
|
{
|
||||||
|
if ((Loaded == false) || (Ioc.IsLocalFile() == false))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return System.IO.File.GetLastWriteTimeUtc(Ioc.Path) > LastChangeDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void LoadData(IKp2aApp app, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status)
|
||||||
|
{
|
||||||
|
Ioc = iocInfo;
|
||||||
|
|
||||||
|
PwDatabase pwDatabase = new PwDatabase();
|
||||||
|
|
||||||
|
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey();
|
||||||
|
key.AddUserKey(new KeePassLib.Keys.KcpPassword(password));
|
||||||
|
if (!String.IsNullOrEmpty(keyfile))
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile));
|
||||||
|
} catch (Exception)
|
||||||
|
{
|
||||||
|
throw new KeyFileException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pwDatabase.Open(iocInfo, key, status);
|
||||||
|
|
||||||
|
if (iocInfo.IsLocalFile())
|
||||||
|
{
|
||||||
|
LastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
LastChangeDate = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Root = pwDatabase.RootGroup;
|
||||||
|
PopulateGlobals(Root);
|
||||||
|
|
||||||
|
|
||||||
|
Loaded = true;
|
||||||
|
KpDatabase = pwDatabase;
|
||||||
|
SearchHelper = new SearchDbHelper(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool QuickUnlockEnabled { get; set; }
|
||||||
|
|
||||||
|
//KeyLength of QuickUnlock at time of loading the database.
|
||||||
|
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
|
||||||
|
public int QuickUnlockKeyLength
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwGroup SearchForText(String str) {
|
||||||
|
PwGroup group = SearchHelper.SearchForText(this, str);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwGroup Search(SearchParameters searchParams)
|
||||||
|
{
|
||||||
|
return SearchHelper.Search(this, searchParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PwGroup SearchForExactUrl(String url) {
|
||||||
|
PwGroup group = SearchHelper.SearchForExactUrl(this, url);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
||||||
|
PwGroup group = SearchHelper.SearchForHost(this, url, allowSubdomains);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SaveData(Context ctx) {
|
||||||
|
|
||||||
|
KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions);
|
||||||
|
KpDatabase.Save(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateGlobals (PwGroup currentGroup)
|
||||||
|
{
|
||||||
|
|
||||||
|
var childGroups = currentGroup.Groups;
|
||||||
|
var childEntries = currentGroup.Entries;
|
||||||
|
|
||||||
|
foreach (PwEntry e in childEntries) {
|
||||||
|
Entries [e.Uuid] = e;
|
||||||
|
}
|
||||||
|
foreach (PwGroup g in childGroups) {
|
||||||
|
Groups[g.Uuid] = g;
|
||||||
|
PopulateGlobals(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear() {
|
||||||
|
Groups.Clear();
|
||||||
|
Entries.Clear();
|
||||||
|
Dirty.Clear();
|
||||||
|
DrawableFactory.Clear();
|
||||||
|
|
||||||
|
Root = null;
|
||||||
|
KpDatabase = null;
|
||||||
|
Ioc = null;
|
||||||
|
_loaded = false;
|
||||||
|
_locked = false;
|
||||||
|
_reloadRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkAllGroupsAsDirty() {
|
||||||
|
foreach ( PwGroup group in Groups.Values ) {
|
||||||
|
Dirty.Add(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,16 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@ -33,34 +24,34 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
public delegate void ActionToPerformOnFinsh(bool success, String message);
|
public delegate void ActionToPerformOnFinsh(bool success, String message);
|
||||||
|
|
||||||
ActionToPerformOnFinsh actionToPerform;
|
readonly ActionToPerformOnFinsh _actionToPerform;
|
||||||
|
|
||||||
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform) : base(null, null)
|
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform) : base(null, null)
|
||||||
{
|
{
|
||||||
this.actionToPerform = actionToPerform;
|
_actionToPerform = actionToPerform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(finish)
|
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(finish)
|
||||||
{
|
{
|
||||||
this.actionToPerform = actionToPerform;
|
_actionToPerform = actionToPerform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, Handler handler) : base(handler)
|
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, Handler handler) : base(handler)
|
||||||
{
|
{
|
||||||
this.actionToPerform = actionToPerform;
|
_actionToPerform = actionToPerform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run()
|
public override void Run()
|
||||||
{
|
{
|
||||||
if (this.mMessage == null)
|
if (Message == null)
|
||||||
this.mMessage = "";
|
Message = "";
|
||||||
if (this.mHandler != null)
|
if (Handler != null)
|
||||||
{
|
{
|
||||||
this.mHandler.Post(() => {actionToPerform(this.mSuccess, this.mMessage);});
|
Handler.Post(() => {_actionToPerform(Success, Message);});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
actionToPerform(this.mSuccess, this.mMessage);
|
_actionToPerform(Success, Message);
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,79 +15,69 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
public class AddEntry : RunnableOnFinish {
|
public class AddEntry : RunnableOnFinish {
|
||||||
protected Database mDb;
|
protected Database Db;
|
||||||
private PwEntry mEntry;
|
private readonly PwEntry _entry;
|
||||||
private PwGroup mParentGroup;
|
private readonly PwGroup _parentGroup;
|
||||||
private Context mCtx;
|
private readonly Context _ctx;
|
||||||
|
|
||||||
public static AddEntry getInstance(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
|
public static AddEntry GetInstance(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
|
||||||
|
|
||||||
return new AddEntry(ctx, db, entry, parentGroup, finish);
|
return new AddEntry(ctx, db, entry, parentGroup, finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AddEntry(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(finish) {
|
protected AddEntry(Context ctx, Database db, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mParentGroup = parentGroup;
|
_parentGroup = parentGroup;
|
||||||
mDb = db;
|
Db = db;
|
||||||
mEntry = entry;
|
_entry = entry;
|
||||||
|
|
||||||
mFinish = new AfterAdd(db, entry, mFinish);
|
OnFinishToRun = new AfterAdd(db, entry, OnFinishToRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
mParentGroup.AddEntry(mEntry, true);
|
_parentGroup.AddEntry(_entry, true);
|
||||||
|
|
||||||
// Commit to disk
|
// Commit to disk
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
|
SaveDb save = new SaveDb(_ctx, Db, OnFinishToRun);
|
||||||
save.run();
|
save.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterAdd : OnFinish {
|
private class AfterAdd : OnFinish {
|
||||||
protected Database mDb;
|
private readonly Database _db;
|
||||||
private PwEntry mEntry;
|
private readonly PwEntry _entry;
|
||||||
|
|
||||||
public AfterAdd(Database db, PwEntry entry, OnFinish finish):base(finish) {
|
public AfterAdd(Database db, PwEntry entry, OnFinish finish):base(finish) {
|
||||||
mDb = db;
|
_db = db;
|
||||||
mEntry = entry;
|
_entry = entry;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
|
|
||||||
PwGroup parent = mEntry.ParentGroup;
|
PwGroup parent = _entry.ParentGroup;
|
||||||
|
|
||||||
// Mark parent group dirty
|
// Mark parent group dirty
|
||||||
mDb.dirty.Add(parent);
|
_db.Dirty.Add(parent);
|
||||||
|
|
||||||
// Add entry to global
|
// Add entry to global
|
||||||
mDb.entries[mEntry.Uuid] = mEntry;
|
_db.Entries[_entry.Uuid] = _entry;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//TODO test fail
|
//TODO test fail
|
||||||
mEntry.ParentGroup.Entries.Remove(mEntry);
|
_entry.ParentGroup.Entries.Remove(_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,82 +16,71 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class AddGroup : RunnableOnFinish {
|
public class AddGroup : RunnableOnFinish {
|
||||||
internal Database mDb;
|
internal Database Db;
|
||||||
private String mName;
|
private readonly String _name;
|
||||||
private int mIconID;
|
private readonly int _iconId;
|
||||||
internal PwGroup mGroup;
|
internal PwGroup Group;
|
||||||
internal PwGroup mParent;
|
internal PwGroup Parent;
|
||||||
protected bool mDontSave;
|
protected bool DontSave;
|
||||||
Context mCtx;
|
readonly Context _ctx;
|
||||||
|
|
||||||
|
|
||||||
public static AddGroup getInstance(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave) {
|
public static AddGroup GetInstance(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave) {
|
||||||
return new AddGroup(ctx, db, name, iconid, parent, finish, dontSave);
|
return new AddGroup(ctx, db, name, iconid, parent, finish, dontSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private AddGroup(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave): base(finish) {
|
private AddGroup(Context ctx, Database db, String name, int iconid, PwGroup parent, OnFinish finish, bool dontSave): base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
Db = db;
|
||||||
mName = name;
|
_name = name;
|
||||||
mIconID = iconid;
|
_iconId = iconid;
|
||||||
mParent = parent;
|
Parent = parent;
|
||||||
mDontSave = dontSave;
|
DontSave = dontSave;
|
||||||
|
|
||||||
mFinish = new AfterAdd(this, mFinish);
|
OnFinishToRun = new AfterAdd(this, OnFinishToRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
PwDatabase pm = mDb.pm;
|
|
||||||
|
|
||||||
// Generate new group
|
// Generate new group
|
||||||
mGroup = new PwGroup(true, true, mName, (PwIcon)mIconID);
|
Group = new PwGroup(true, true, _name, (PwIcon)_iconId);
|
||||||
mParent.AddGroup(mGroup, true);
|
Parent.AddGroup(Group, true);
|
||||||
|
|
||||||
// Commit to disk
|
// Commit to disk
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
|
SaveDb save = new SaveDb(_ctx, Db, OnFinishToRun, DontSave);
|
||||||
save.run();
|
save.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterAdd : OnFinish {
|
private class AfterAdd : OnFinish {
|
||||||
|
readonly AddGroup _addGroup;
|
||||||
AddGroup addGroup;
|
|
||||||
|
|
||||||
public AfterAdd(AddGroup addGroup,OnFinish finish): base(finish) {
|
public AfterAdd(AddGroup addGroup,OnFinish finish): base(finish) {
|
||||||
this.addGroup = addGroup;
|
_addGroup = addGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
|
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
// Mark parent group dirty
|
// Mark parent group dirty
|
||||||
addGroup.mDb.dirty.Add(addGroup.mParent);
|
_addGroup.Db.Dirty.Add(_addGroup.Parent);
|
||||||
|
|
||||||
// Add group to global list
|
// Add group to global list
|
||||||
addGroup.mDb.groups[addGroup.mGroup.Uuid] = addGroup.mGroup;
|
_addGroup.Db.Groups[_addGroup.Group.Uuid] = _addGroup.Group;
|
||||||
} else {
|
} else {
|
||||||
addGroup.mParent.Groups.Remove(addGroup.mGroup);
|
_addGroup.Parent.Groups.Remove(_addGroup.Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
78
src/Kp2aBusinessLogic/database/edit/CreateDB.cs
Normal file
78
src/Kp2aBusinessLogic/database/edit/CreateDB.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||||
|
|
||||||
|
Keepass2Android is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Keepass2Android is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Android.Content;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using KeePassLib.Keys;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
|
||||||
|
public class CreateDb : RunnableOnFinish {
|
||||||
|
|
||||||
|
private const int DefaultEncryptionRounds = 1000;
|
||||||
|
|
||||||
|
private readonly IOConnectionInfo _ioc;
|
||||||
|
private readonly bool _dontSave;
|
||||||
|
private readonly Context _ctx;
|
||||||
|
private readonly IKp2aApp _app;
|
||||||
|
|
||||||
|
public CreateDb(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) {
|
||||||
|
_ctx = ctx;
|
||||||
|
_ioc = ioc;
|
||||||
|
_dontSave = dontSave;
|
||||||
|
_app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void Run() {
|
||||||
|
Database db = _app.CreateNewDatabase();
|
||||||
|
|
||||||
|
db.KpDatabase = new KeePassLib.PwDatabase();
|
||||||
|
//Key will be changed/created immediately after creation:
|
||||||
|
CompositeKey tempKey = new CompositeKey();
|
||||||
|
db.KpDatabase.New(_ioc, tempKey);
|
||||||
|
|
||||||
|
|
||||||
|
db.KpDatabase.KeyEncryptionRounds = DefaultEncryptionRounds;
|
||||||
|
db.KpDatabase.Name = "Keepass2Android Password Database";
|
||||||
|
|
||||||
|
|
||||||
|
// Set Database state
|
||||||
|
db.Root = db.KpDatabase.RootGroup;
|
||||||
|
db.Ioc = _ioc;
|
||||||
|
db.Loaded = true;
|
||||||
|
db.SearchHelper = new SearchDbHelper(_app);
|
||||||
|
|
||||||
|
// Add a couple default groups
|
||||||
|
AddGroup internet = AddGroup.GetInstance(_ctx, db, "Internet", 1, db.KpDatabase.RootGroup, null, true);
|
||||||
|
internet.Run();
|
||||||
|
AddGroup email = AddGroup.GetInstance(_ctx, db, "eMail", 19, db.KpDatabase.RootGroup, null, true);
|
||||||
|
email.Run();
|
||||||
|
|
||||||
|
// Commit changes
|
||||||
|
SaveDb save = new SaveDb(_ctx, db, OnFinishToRun, _dontSave);
|
||||||
|
OnFinishToRun = null;
|
||||||
|
save.Run();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,28 +16,19 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
public class DeleteEntry : DeleteRunnable {
|
public class DeleteEntry : DeleteRunnable {
|
||||||
|
|
||||||
private PwEntry mEntry;
|
|
||||||
|
|
||||||
public DeleteEntry(Context ctx, Database db, PwEntry entry, OnFinish finish):base(finish) {
|
private readonly PwEntry _entry;
|
||||||
mCtx = ctx;
|
|
||||||
mDb = db;
|
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
|
||||||
mEntry = entry;
|
Ctx = ctx;
|
||||||
|
Db = app.GetDb();
|
||||||
|
_entry = entry;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,27 +36,27 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return CanRecycleGroup(mEntry.ParentGroup);
|
return CanRecycleGroup(_entry.ParentGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override int QuestionsResourceId
|
protected override UiStringKey QuestionsResourceId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Resource.String.AskDeletePermanentlyEntry;
|
return UiStringKey.AskDeletePermanentlyEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
|
|
||||||
PwDatabase pd = mDb.pm;
|
PwDatabase pd = Db.KpDatabase;
|
||||||
|
|
||||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||||
|
|
||||||
bool bUpdateGroupList = false;
|
bool bUpdateGroupList = false;
|
||||||
DateTime dtNow = DateTime.Now;
|
DateTime dtNow = DateTime.Now;
|
||||||
PwEntry pe = mEntry;
|
PwEntry pe = _entry;
|
||||||
PwGroup pgParent = pe.ParentGroup;
|
PwGroup pgParent = pe.ParentGroup;
|
||||||
if(pgParent != null)
|
if(pgParent != null)
|
||||||
{
|
{
|
||||||
@ -77,19 +68,19 @@ namespace keepass2android
|
|||||||
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
|
PwDeletedObject pdo = new PwDeletedObject(pe.Uuid, dtNow);
|
||||||
pd.DeletedObjects.Add(pdo);
|
pd.DeletedObjects.Add(pdo);
|
||||||
|
|
||||||
mFinish = new ActionOnFinish( (success, message) =>
|
OnFinishToRun = new ActionOnFinish((success, message) =>
|
||||||
{
|
{
|
||||||
if ( success ) {
|
if (success)
|
||||||
// Mark parent dirty
|
{
|
||||||
if ( pgParent != null ) {
|
// Mark parent dirty
|
||||||
mDb.dirty.Add(pgParent);
|
Db.Dirty.Add(pgParent);
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
{
|
||||||
App.setShutdown();
|
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
||||||
}
|
App.SetShutdown();
|
||||||
|
}
|
||||||
}, this.mFinish);
|
}, OnFinishToRun);
|
||||||
}
|
}
|
||||||
else // Recycle
|
else // Recycle
|
||||||
{
|
{
|
||||||
@ -98,27 +89,25 @@ namespace keepass2android
|
|||||||
pgRecycleBin.AddEntry(pe, true, true);
|
pgRecycleBin.AddEntry(pe, true, true);
|
||||||
pe.Touch(false);
|
pe.Touch(false);
|
||||||
|
|
||||||
mFinish = new ActionOnFinish( (success, message) =>
|
OnFinishToRun = new ActionOnFinish( (success, message) =>
|
||||||
{
|
{
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
// Mark previous parent dirty
|
// Mark previous parent dirty
|
||||||
if ( pgParent != null ) {
|
Db.Dirty.Add(pgParent);
|
||||||
mDb.dirty.Add(pgParent);
|
|
||||||
}
|
|
||||||
// Mark new parent dirty
|
// Mark new parent dirty
|
||||||
mDb.dirty.Add(pgRecycleBin);
|
Db.Dirty.Add(pgRecycleBin);
|
||||||
} else {
|
} else {
|
||||||
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
// Let's not bother recovering from a failure to save a deleted entry. It is too much work.
|
||||||
App.setShutdown();
|
App.SetShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, this.mFinish);
|
}, OnFinishToRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit database
|
// Commit database
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish, false);
|
SaveDb save = new SaveDb(Ctx, Db, OnFinishToRun, false);
|
||||||
save.run();
|
save.Run();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -16,16 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -33,55 +24,58 @@ namespace keepass2android
|
|||||||
|
|
||||||
public class DeleteGroup : DeleteRunnable {
|
public class DeleteGroup : DeleteRunnable {
|
||||||
|
|
||||||
private PwGroup mGroup;
|
private PwGroup _group;
|
||||||
private GroupBaseActivity mAct;
|
protected bool DontSave;
|
||||||
protected bool mDontSave;
|
|
||||||
|
|
||||||
public DeleteGroup(Context ctx, Database db, PwGroup group, GroupBaseActivity act, OnFinish finish):base(finish) {
|
public DeleteGroup(Context ctx, IKp2aApp app, PwGroup group, OnFinish finish)
|
||||||
setMembers(ctx, db, group, act, false);
|
: base(finish, app)
|
||||||
|
{
|
||||||
|
SetMembers(ctx, app, group, false);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
public DeleteGroup(Context ctx, Database db, PwGroup group, GroupBaseActivity act, OnFinish finish, bool dontSave):base(finish) {
|
public DeleteGroup(Context ctx, Database db, PwGroup group, Activity act, OnFinish finish, bool dontSave)
|
||||||
setMembers(ctx, db, group, act, dontSave);
|
: base(finish)
|
||||||
|
{
|
||||||
|
SetMembers(ctx, db, group, act, dontSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, bool dontSave):base(finish) {
|
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, bool dontSave):base(finish) {
|
||||||
setMembers(ctx, db, group, null, dontSave);
|
SetMembers(ctx, db, group, null, dontSave);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
private void setMembers(Context ctx, Database db, PwGroup group, GroupBaseActivity act, bool dontSave) {
|
private void SetMembers(Context ctx, IKp2aApp app, PwGroup group, bool dontSave)
|
||||||
base.setMembers(ctx, db);
|
{
|
||||||
|
base.SetMembers(ctx, app.GetDb());
|
||||||
mGroup = group;
|
|
||||||
mAct = act;
|
|
||||||
mDontSave = dontSave;
|
|
||||||
|
|
||||||
|
_group = group;
|
||||||
|
DontSave = dontSave;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanRecycle
|
public override bool CanRecycle
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return CanRecycleGroup(mGroup);
|
return CanRecycleGroup(_group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override int QuestionsResourceId
|
protected override UiStringKey QuestionsResourceId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Resource.String.AskDeletePermanentlyGroup;
|
return UiStringKey.AskDeletePermanentlyGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
//from KP Desktop
|
//from KP Desktop
|
||||||
PwGroup pg = mGroup;
|
PwGroup pg = _group;
|
||||||
PwGroup pgParent = pg.ParentGroup;
|
PwGroup pgParent = pg.ParentGroup;
|
||||||
if(pgParent == null) return; // Can't remove virtual or root group
|
if(pgParent == null) return; // Can't remove virtual or root group
|
||||||
|
|
||||||
PwDatabase pd = mDb.pm;
|
PwDatabase pd = Db.KpDatabase;
|
||||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||||
|
|
||||||
pgParent.Groups.Remove(pg);
|
pgParent.Groups.Remove(pg);
|
||||||
@ -92,7 +86,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
|
PwDeletedObject pdo = new PwDeletedObject(pg.Uuid, DateTime.Now);
|
||||||
pd.DeletedObjects.Add(pdo);
|
pd.DeletedObjects.Add(pdo);
|
||||||
mFinish = new AfterDeletePermanently(mFinish, mDb, mGroup);
|
OnFinishToRun = new AfterDeletePermanently(OnFinishToRun, App, _group);
|
||||||
}
|
}
|
||||||
else // Recycle
|
else // Recycle
|
||||||
{
|
{
|
||||||
@ -101,59 +95,59 @@ namespace keepass2android
|
|||||||
|
|
||||||
pgRecycleBin.AddGroup(pg, true, true);
|
pgRecycleBin.AddGroup(pg, true, true);
|
||||||
pg.Touch(false);
|
pg.Touch(false);
|
||||||
mFinish = new ActionOnFinish((success, message) =>
|
OnFinishToRun = new ActionOnFinish((success, message) =>
|
||||||
{
|
{
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
// Mark new parent (Recycle bin) dirty
|
// Mark new parent (Recycle bin) dirty
|
||||||
PwGroup parent = mGroup.ParentGroup;
|
PwGroup parent = _group.ParentGroup;
|
||||||
if ( parent != null ) {
|
if ( parent != null ) {
|
||||||
mDb.dirty.Add(parent);
|
Db.Dirty.Add(parent);
|
||||||
}
|
}
|
||||||
//Mark old parent dirty:
|
//Mark old parent dirty:
|
||||||
mDb.dirty.Add(pgParent);
|
Db.Dirty.Add(pgParent);
|
||||||
} else {
|
} else {
|
||||||
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
||||||
App.setShutdown();
|
App.SetShutdown();
|
||||||
}
|
}
|
||||||
}, this.mFinish);
|
}, OnFinishToRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
|
SaveDb save = new SaveDb(Ctx, Db, OnFinishToRun, DontSave);
|
||||||
save.run();
|
save.Run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class AfterDeletePermanently : OnFinish {
|
private class AfterDeletePermanently : OnFinish {
|
||||||
Database mDb;
|
readonly IKp2aApp _app;
|
||||||
|
|
||||||
PwGroup mGroup;
|
readonly PwGroup _group;
|
||||||
|
|
||||||
public AfterDeletePermanently(OnFinish finish, Database db, PwGroup group):base(finish) {
|
public AfterDeletePermanently(OnFinish finish, IKp2aApp app, PwGroup group):base(finish) {
|
||||||
this.mDb = db;
|
_app = app;
|
||||||
this.mGroup = group;
|
_group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
// Remove from group global
|
// Remove from group global
|
||||||
mDb.groups.Remove(mGroup.Uuid);
|
_app.GetDb().Groups.Remove(_group.Uuid);
|
||||||
|
|
||||||
// Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw)
|
// Remove group from the dirty global (if it is present), not a big deal if this fails (doesn't throw)
|
||||||
mDb.dirty.Remove(mGroup);
|
_app.GetDb().Dirty.Remove(_group);
|
||||||
|
|
||||||
// Mark parent dirty
|
// Mark parent dirty
|
||||||
PwGroup parent = mGroup.ParentGroup;
|
PwGroup parent = _group.ParentGroup;
|
||||||
if ( parent != null ) {
|
if ( parent != null ) {
|
||||||
mDb.dirty.Add(parent);
|
_app.GetDb().Dirty.Add(parent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
// Let's not bother recovering from a failure to save a deleted group. It is too much work.
|
||||||
App.setShutdown();
|
_app.SetShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
134
src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs
Normal file
134
src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using Android.Content;
|
||||||
|
using KeePassLib;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
public abstract class DeleteRunnable : RunnableOnFinish
|
||||||
|
{
|
||||||
|
protected DeleteRunnable(OnFinish finish, IKp2aApp app):base(finish)
|
||||||
|
{
|
||||||
|
App = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IKp2aApp App;
|
||||||
|
|
||||||
|
protected Database Db;
|
||||||
|
|
||||||
|
protected Context Ctx;
|
||||||
|
|
||||||
|
protected void SetMembers(Context ctx, Database db)
|
||||||
|
{
|
||||||
|
Ctx = ctx;
|
||||||
|
Db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool _deletePermanently = true;
|
||||||
|
|
||||||
|
public bool DeletePermanently
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _deletePermanently;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_deletePermanently = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract bool CanRecycle
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool CanRecycleGroup(PwGroup pgParent)
|
||||||
|
{
|
||||||
|
bool bShiftPressed = false;
|
||||||
|
PwDatabase pd = Db.KpDatabase;
|
||||||
|
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
||||||
|
bool bPermanent = false;
|
||||||
|
if (pgParent != null)
|
||||||
|
{
|
||||||
|
if (pd.RecycleBinEnabled == false)
|
||||||
|
bPermanent = true;
|
||||||
|
else if (bShiftPressed)
|
||||||
|
bPermanent = true;
|
||||||
|
else if (pgRecycleBin == null)
|
||||||
|
{
|
||||||
|
} // Recycle
|
||||||
|
else if (pgParent == pgRecycleBin)
|
||||||
|
bPermanent = true;
|
||||||
|
else if (pgParent.IsContainedIn(pgRecycleBin))
|
||||||
|
bPermanent = true;
|
||||||
|
}
|
||||||
|
return !bPermanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void EnsureRecycleBin(ref PwGroup pgRecycleBin,
|
||||||
|
ref bool bGroupListUpdateRequired)
|
||||||
|
{
|
||||||
|
if ((Db == null) || (Db.KpDatabase == null)) { return; }
|
||||||
|
|
||||||
|
if(pgRecycleBin == Db.KpDatabase.RootGroup)
|
||||||
|
{
|
||||||
|
pgRecycleBin = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pgRecycleBin == null)
|
||||||
|
{
|
||||||
|
pgRecycleBin = new PwGroup(true, true, App.GetResourceString(UiStringKey.RecycleBin),
|
||||||
|
PwIcon.TrashBin)
|
||||||
|
{
|
||||||
|
EnableAutoType = false,
|
||||||
|
EnableSearching = false,
|
||||||
|
IsExpanded = false
|
||||||
|
};
|
||||||
|
|
||||||
|
Db.KpDatabase.RootGroup.AddGroup(pgRecycleBin, true);
|
||||||
|
|
||||||
|
Db.KpDatabase.RecycleBinUuid = pgRecycleBin.Uuid;
|
||||||
|
|
||||||
|
bGroupListUpdateRequired = true;
|
||||||
|
}
|
||||||
|
else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(Db.KpDatabase.RecycleBinUuid)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract UiStringKey QuestionsResourceId
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
if (CanRecycle)
|
||||||
|
{
|
||||||
|
App.AskYesNoCancel(UiStringKey.AskDeletePermanently_title,
|
||||||
|
QuestionsResourceId,
|
||||||
|
(dlgSender, dlgEvt) =>
|
||||||
|
{
|
||||||
|
DeletePermanently = true;
|
||||||
|
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
|
||||||
|
pt.Run();
|
||||||
|
},
|
||||||
|
(dlgSender, dlgEvt) => {
|
||||||
|
DeletePermanently = false;
|
||||||
|
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
|
||||||
|
pt.Run();
|
||||||
|
},
|
||||||
|
(dlgSender, dlgEvt) => {},
|
||||||
|
Ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
|
||||||
|
pt.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,34 +16,21 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
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;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class FileOnFinish : OnFinish {
|
public abstract class FileOnFinish : OnFinish {
|
||||||
private String mFilename = "";
|
private String _filename = "";
|
||||||
|
|
||||||
public FileOnFinish(FileOnFinish finish):base(finish) {
|
protected FileOnFinish(FileOnFinish finish):base(finish) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilename(String filename) {
|
public string Filename
|
||||||
mFilename = filename;
|
{
|
||||||
|
get { return _filename; }
|
||||||
|
set { _filename = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilename() {
|
|
||||||
return mFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
105
src/Kp2aBusinessLogic/database/edit/LoadDB.cs
Normal file
105
src/Kp2aBusinessLogic/database/edit/LoadDB.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
||||||
|
|
||||||
|
Keepass2Android is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Keepass2Android is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
public class LoadDb : RunnableOnFinish {
|
||||||
|
private readonly IOConnectionInfo _ioc;
|
||||||
|
private readonly String _pass;
|
||||||
|
private readonly String _key;
|
||||||
|
private readonly IKp2aApp _app;
|
||||||
|
private readonly bool _rememberKeyfile;
|
||||||
|
|
||||||
|
public LoadDb(IKp2aApp app, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish)
|
||||||
|
{
|
||||||
|
_app = app;
|
||||||
|
_ioc = ioc;
|
||||||
|
_pass = pass;
|
||||||
|
_key = key;
|
||||||
|
|
||||||
|
|
||||||
|
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void Run ()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_app.GetDb().LoadData (_app, _ioc, _pass, _key, Status);
|
||||||
|
|
||||||
|
SaveFileData (_ioc, _key);
|
||||||
|
|
||||||
|
} catch (KeyFileException) {
|
||||||
|
Finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ _app.GetResourceString(UiStringKey.keyfile_does_not_exist));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Finish(false, "An error occured: " + e.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* catch (InvalidPasswordException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.InvalidPassword));
|
||||||
|
return;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.FileNotFound));
|
||||||
|
return;
|
||||||
|
} catch (IOException e) {
|
||||||
|
finish(false, e.getMessage());
|
||||||
|
return;
|
||||||
|
} catch (KeyFileEmptyException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.keyfile_is_empty));
|
||||||
|
return;
|
||||||
|
} catch (InvalidAlgorithmException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.invalid_algorithm));
|
||||||
|
return;
|
||||||
|
} catch (InvalidKeyFileException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.keyfile_does_not_exist));
|
||||||
|
return;
|
||||||
|
} catch (InvalidDBSignatureException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.invalid_db_sig));
|
||||||
|
return;
|
||||||
|
} catch (InvalidDBVersionException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.unsupported_db_version));
|
||||||
|
return;
|
||||||
|
} catch (InvalidDBException e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.error_invalid_db));
|
||||||
|
return;
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
finish(false, Ctx.GetString(Resource.String.error_out_of_memory));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Finish(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveFileData(IOConnectionInfo ioc, String key) {
|
||||||
|
|
||||||
|
if (!_rememberKeyfile)
|
||||||
|
{
|
||||||
|
key = "";
|
||||||
|
}
|
||||||
|
_app.StoreOpenedFileAsRecent(ioc, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,72 +16,65 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
public abstract class OnFinish
|
public abstract class OnFinish
|
||||||
{
|
{
|
||||||
protected bool mSuccess;
|
protected bool Success;
|
||||||
protected String mMessage;
|
protected String Message;
|
||||||
|
|
||||||
protected OnFinish mOnFinish;
|
protected OnFinish BaseOnFinish;
|
||||||
protected Handler mHandler;
|
protected Handler Handler;
|
||||||
|
|
||||||
public OnFinish() {
|
protected OnFinish() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnFinish(Handler handler) {
|
||||||
|
BaseOnFinish = null;
|
||||||
|
Handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnFinish(OnFinish finish, Handler handler) {
|
||||||
|
BaseOnFinish = finish;
|
||||||
|
Handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OnFinish(OnFinish finish) {
|
||||||
|
BaseOnFinish = finish;
|
||||||
|
Handler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnFinish(Handler handler) {
|
public void SetResult(bool success, String message) {
|
||||||
mOnFinish = null;
|
Success = success;
|
||||||
mHandler = handler;
|
Message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnFinish(OnFinish finish, Handler handler) {
|
public void SetResult(bool success) {
|
||||||
mOnFinish = finish;
|
Success = success;
|
||||||
mHandler = handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnFinish(OnFinish finish) {
|
public virtual void Run() {
|
||||||
mOnFinish = finish;
|
if ( BaseOnFinish != null ) {
|
||||||
mHandler = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResult(bool success, String message) {
|
|
||||||
mSuccess = success;
|
|
||||||
mMessage = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResult(bool success) {
|
|
||||||
mSuccess = success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void run() {
|
|
||||||
if ( mOnFinish != null ) {
|
|
||||||
// Pass on result on call finish
|
// Pass on result on call finish
|
||||||
mOnFinish.setResult(mSuccess, mMessage);
|
BaseOnFinish.SetResult(Success, Message);
|
||||||
|
|
||||||
if ( mHandler != null ) {
|
if ( Handler != null ) {
|
||||||
mHandler.Post(mOnFinish.run);
|
Handler.Post(BaseOnFinish.Run);
|
||||||
} else {
|
} else {
|
||||||
mOnFinish.run();
|
BaseOnFinish.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void displayMessage(Context ctx) {
|
protected void DisplayMessage(Context ctx) {
|
||||||
displayMessage(ctx, mMessage);
|
DisplayMessage(ctx, Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void displayMessage(Context ctx, string message)
|
public static void DisplayMessage(Context ctx, string message)
|
||||||
{
|
{
|
||||||
if ( !String.IsNullOrEmpty(message) ) {
|
if ( !String.IsNullOrEmpty(message) ) {
|
||||||
Toast.MakeText(ctx, message, ToastLength.Long).Show();
|
Toast.MakeText(ctx, message, ToastLength.Long).Show();
|
@ -14,32 +14,39 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
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 Android.Graphics.Drawables;
|
|
||||||
using Android.Content.Res;
|
|
||||||
using Android.Graphics;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class BitmapDrawableCompat {
|
|
||||||
|
|
||||||
public static BitmapDrawable getBitmapDrawable(Resources res, Bitmap bitmap) {
|
public abstract class RunnableOnFinish {
|
||||||
return new BitmapDrawable(res, bitmap);
|
|
||||||
|
public OnFinish OnFinishToRun;
|
||||||
|
public UpdateStatus Status;
|
||||||
|
|
||||||
|
protected RunnableOnFinish(OnFinish finish) {
|
||||||
|
OnFinishToRun = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void Finish(bool result, String message) {
|
||||||
|
if ( OnFinishToRun != null ) {
|
||||||
|
OnFinishToRun.SetResult(result, message);
|
||||||
|
OnFinishToRun.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Finish(bool result) {
|
||||||
|
if ( OnFinishToRun != null ) {
|
||||||
|
OnFinishToRun.SetResult(result);
|
||||||
|
OnFinishToRun.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStatus(UpdateStatus status) {
|
||||||
|
Status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public void Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -15,46 +15,37 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class SaveDB : RunnableOnFinish {
|
public class SaveDb : RunnableOnFinish {
|
||||||
private Database mDb;
|
private readonly Database _db;
|
||||||
private bool mDontSave;
|
private readonly bool _dontSave;
|
||||||
private Context mCtx;
|
private readonly Context _ctx;
|
||||||
|
|
||||||
public SaveDB(Context ctx, Database db, OnFinish finish, bool dontSave): base(finish) {
|
public SaveDb(Context ctx, Database db, OnFinish finish, bool dontSave): base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
_db = db;
|
||||||
mDontSave = dontSave;
|
_dontSave = dontSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SaveDB(Context ctx, Database db, OnFinish finish):base(finish) {
|
public SaveDb(Context ctx, Database db, OnFinish finish):base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
_db = db;
|
||||||
mDontSave = false;
|
_dontSave = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run ()
|
public override void Run ()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! mDontSave) {
|
if (! _dontSave) {
|
||||||
try {
|
try {
|
||||||
mDb.SaveData (mCtx);
|
_db.SaveData (_ctx);
|
||||||
if (mDb.mIoc.IsLocalFile())
|
if (_db.Ioc.IsLocalFile())
|
||||||
mDb.mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(mDb.mIoc.Path);
|
_db.LastChangeDate = System.IO.File.GetLastWriteTimeUtc(_db.Ioc.Path);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
/* TODO KPDesktop:
|
/* TODO KPDesktop:
|
||||||
* catch(Exception exSave)
|
* catch(Exception exSave)
|
||||||
@ -63,12 +54,12 @@ namespace keepass2android
|
|||||||
bSuccess = false;
|
bSuccess = false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
finish (false, e.Message);
|
Finish (false, e.Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish(true);
|
Finish(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,16 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using KeePassLib.Keys;
|
using KeePassLib.Keys;
|
||||||
|
|
||||||
@ -32,40 +23,40 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
public class SetPassword : RunnableOnFinish {
|
public class SetPassword : RunnableOnFinish {
|
||||||
|
|
||||||
private String mPassword;
|
private readonly String _password;
|
||||||
private String mKeyfile;
|
private readonly String _keyfile;
|
||||||
private Database mDb;
|
private readonly Database _db;
|
||||||
private bool mDontSave;
|
private readonly bool _dontSave;
|
||||||
private Context mCtx;
|
private readonly Context _ctx;
|
||||||
|
|
||||||
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish): base(finish) {
|
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish): base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
_db = db;
|
||||||
mPassword = password;
|
_password = password;
|
||||||
mKeyfile = keyfile;
|
_keyfile = keyfile;
|
||||||
mDontSave = false;
|
_dontSave = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, bool dontSave): base(finish) {
|
public SetPassword(Context ctx, Database db, String password, String keyfile, OnFinish finish, bool dontSave): base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
_db = db;
|
||||||
mPassword = password;
|
_password = password;
|
||||||
mKeyfile = keyfile;
|
_keyfile = keyfile;
|
||||||
mDontSave = dontSave;
|
_dontSave = dontSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run ()
|
public override void Run ()
|
||||||
{
|
{
|
||||||
PwDatabase pm = mDb.pm;
|
PwDatabase pm = _db.KpDatabase;
|
||||||
CompositeKey newKey = new CompositeKey ();
|
CompositeKey newKey = new CompositeKey ();
|
||||||
if (String.IsNullOrEmpty (mPassword) == false) {
|
if (String.IsNullOrEmpty (_password) == false) {
|
||||||
newKey.AddUserKey (new KcpPassword (mPassword));
|
newKey.AddUserKey (new KcpPassword (_password));
|
||||||
}
|
}
|
||||||
if (String.IsNullOrEmpty (mKeyfile) == false) {
|
if (String.IsNullOrEmpty (_keyfile) == false) {
|
||||||
try {
|
try {
|
||||||
newKey.AddUserKey (new KcpKeyFile (mKeyfile));
|
newKey.AddUserKey (new KcpKeyFile (_keyfile));
|
||||||
} catch (Exception exKF) {
|
} catch (Exception) {
|
||||||
//TODO MessageService.ShowWarning (strKeyFile, KPRes.KeyFileError, exKF);
|
//TODO MessageService.ShowWarning (strKeyFile, KPRes.KeyFileError, exKF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -78,29 +69,29 @@ namespace keepass2android
|
|||||||
pm.MasterKey = newKey;
|
pm.MasterKey = newKey;
|
||||||
|
|
||||||
// Save Database
|
// Save Database
|
||||||
mFinish = new AfterSave(previousKey, previousMasterKeyChanged, pm, mFinish);
|
OnFinishToRun = new AfterSave(previousKey, previousMasterKeyChanged, pm, OnFinishToRun);
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish, mDontSave);
|
SaveDb save = new SaveDb(_ctx, _db, OnFinishToRun, _dontSave);
|
||||||
save.run();
|
save.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterSave : OnFinish {
|
private class AfterSave : OnFinish {
|
||||||
private CompositeKey mBackup;
|
private readonly CompositeKey _backup;
|
||||||
private DateTime mPreviousKeyChanged;
|
private readonly DateTime _previousKeyChanged;
|
||||||
private PwDatabase mDb;
|
private readonly PwDatabase _db;
|
||||||
|
|
||||||
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
|
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
|
||||||
mPreviousKeyChanged = previousKeyChanged;
|
_previousKeyChanged = previousKeyChanged;
|
||||||
mBackup = backup;
|
_backup = backup;
|
||||||
mDb = db;
|
_db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( ! mSuccess ) {
|
if ( ! Success ) {
|
||||||
mDb.MasterKey = mBackup;
|
_db.MasterKey = _backup;
|
||||||
mDb.MasterKeyChanged = mPreviousKeyChanged;
|
_db.MasterKeyChanged = _previousKeyChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,81 +15,67 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class UpdateEntry : RunnableOnFinish {
|
public class UpdateEntry : RunnableOnFinish {
|
||||||
private Database mDb;
|
private readonly Database _db;
|
||||||
private PwEntry mOldE;
|
private readonly Context _ctx;
|
||||||
private PwEntry mNewE;
|
|
||||||
private Context mCtx;
|
|
||||||
|
|
||||||
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish):base(finish) {
|
public UpdateEntry(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinish finish):base(finish) {
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mDb = db;
|
_db = db;
|
||||||
mOldE = oldE;
|
|
||||||
mNewE = newE;
|
|
||||||
|
|
||||||
mFinish = new AfterUpdate(oldE, newE, db, finish);
|
OnFinishToRun = new AfterUpdate(oldE, newE, db, finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
// Commit to disk
|
// Commit to disk
|
||||||
SaveDB save = new SaveDB(mCtx, mDb, mFinish);
|
SaveDb save = new SaveDb(_ctx, _db, OnFinishToRun);
|
||||||
save.run();
|
save.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterUpdate : OnFinish {
|
private class AfterUpdate : OnFinish {
|
||||||
private PwEntry mBackup;
|
private readonly PwEntry _backup;
|
||||||
private PwEntry mUpdatedEntry;
|
private readonly PwEntry _updatedEntry;
|
||||||
private Database mDb;
|
private readonly Database _db;
|
||||||
|
|
||||||
public AfterUpdate(PwEntry backup, PwEntry updatedEntry, Database db, OnFinish finish):base(finish) {
|
public AfterUpdate(PwEntry backup, PwEntry updatedEntry, Database db, OnFinish finish):base(finish) {
|
||||||
mBackup = backup;
|
_backup = backup;
|
||||||
mUpdatedEntry = updatedEntry;
|
_updatedEntry = updatedEntry;
|
||||||
mDb = db;
|
_db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
// Mark group dirty if title, icon or Expiry stuff changes
|
// Mark group dirty if title, icon or Expiry stuff changes
|
||||||
if ( ! mBackup.Strings.ReadSafe (PwDefs.TitleField).Equals(mUpdatedEntry.Strings.ReadSafe (PwDefs.TitleField))
|
if ( ! _backup.Strings.ReadSafe (PwDefs.TitleField).Equals(_updatedEntry.Strings.ReadSafe (PwDefs.TitleField))
|
||||||
|| ! mBackup.IconId.Equals(mUpdatedEntry.IconId)
|
|| ! _backup.IconId.Equals(_updatedEntry.IconId)
|
||||||
|| ! mBackup.CustomIconUuid.EqualsValue(mUpdatedEntry.CustomIconUuid)
|
|| ! _backup.CustomIconUuid.EqualsValue(_updatedEntry.CustomIconUuid)
|
||||||
|| mBackup.Expires != mUpdatedEntry.Expires
|
|| _backup.Expires != _updatedEntry.Expires
|
||||||
|| (mBackup.Expires && (! mBackup.ExpiryTime.Equals(mUpdatedEntry.ExpiryTime)))
|
|| (_backup.Expires && (! _backup.ExpiryTime.Equals(_updatedEntry.ExpiryTime)))
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
PwGroup parent = mUpdatedEntry.ParentGroup;
|
PwGroup parent = _updatedEntry.ParentGroup;
|
||||||
if ( parent != null ) {
|
if ( parent != null ) {
|
||||||
|
|
||||||
// Mark parent group dirty
|
// Mark parent group dirty
|
||||||
mDb.dirty.Add(parent);
|
_db.Dirty.Add(parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we fail to save, back out changes to global structure
|
// If we fail to save, back out changes to global structure
|
||||||
//TODO test fail
|
//TODO test fail
|
||||||
mUpdatedEntry.AssignProperties(mBackup, false, true, false);
|
_updatedEntry.AssignProperties(_backup, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
90
src/Kp2aUnitTests/Kp2aUnitTests.csproj
Normal file
90
src/Kp2aUnitTests/Kp2aUnitTests.csproj
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Kp2aUnitTests</RootNamespace>
|
||||||
|
<AssemblyName>Kp2aUnitTests</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AndroidApplication>true</AndroidApplication>
|
||||||
|
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||||
|
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
|
||||||
|
<AndroidLinkMode>None</AndroidLinkMode>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
|
||||||
|
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Mono.Android" />
|
||||||
|
<Reference Include="mscorlib" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="TestDrawableFactory.cs" />
|
||||||
|
<Compile Include="TestCreateDb.cs" />
|
||||||
|
<Compile Include="MainActivity.cs" />
|
||||||
|
<Compile Include="Resources\Resource.Designer.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\AboutResources.txt" />
|
||||||
|
<None Include="Assets\AboutAssets.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\Layout\Main.axml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\Values\Strings.xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AndroidResource Include="Resources\Drawable\Icon.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||||
|
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
||||||
|
<Name>KeePassLib2Android</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
||||||
|
<Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project>
|
||||||
|
<Name>Kp2aBusinessLogic</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj">
|
||||||
|
<Project>{a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48}</Project>
|
||||||
|
<Name>MonoDroidUnitTesting</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
27
src/Kp2aUnitTests/MainActivity.cs
Normal file
27
src/Kp2aUnitTests/MainActivity.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using Android.App;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Runtime;
|
||||||
|
using Android.Views;
|
||||||
|
using Android.Widget;
|
||||||
|
using Android.OS;
|
||||||
|
using MonoDroidUnitTesting;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Kp2aUnitTests
|
||||||
|
{
|
||||||
|
[Activity(Label = "MonoDroidUnit", MainLauncher = true, Icon = "@drawable/icon")]
|
||||||
|
public class MainActivity : GuiTestRunnerActivity
|
||||||
|
{
|
||||||
|
protected override TestRunner CreateTestRunner()
|
||||||
|
{
|
||||||
|
TestRunner runner = new TestRunner();
|
||||||
|
// Run all tests from this assembly
|
||||||
|
runner.AddTests(Assembly.GetExecutingAssembly());
|
||||||
|
return runner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
34
src/Kp2aUnitTests/Properties/AssemblyInfo.cs
Normal file
34
src/Kp2aUnitTests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Android.App;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Kp2aUnitTests")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Kp2aUnitTests")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
||||||
|
// Add some common permissions, these can be removed if not needed
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
|
||||||
|
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
|
50
src/Kp2aUnitTests/Resources/AboutResources.txt
Normal file
50
src/Kp2aUnitTests/Resources/AboutResources.txt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||||
|
in your application as resource files. Various Android APIs are designed to
|
||||||
|
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||||
|
directly.
|
||||||
|
|
||||||
|
For example, a sample Android app that contains a user interface layout (main.xml),
|
||||||
|
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||||
|
would keep its resources in the "Resources" directory of the application:
|
||||||
|
|
||||||
|
Resources/
|
||||||
|
drawable-hdpi/
|
||||||
|
icon.png
|
||||||
|
|
||||||
|
drawable-ldpi/
|
||||||
|
icon.png
|
||||||
|
|
||||||
|
drawable-mdpi/
|
||||||
|
icon.png
|
||||||
|
|
||||||
|
layout/
|
||||||
|
main.xml
|
||||||
|
|
||||||
|
values/
|
||||||
|
strings.xml
|
||||||
|
|
||||||
|
In order to get the build system to recognize Android resources, set the build action to
|
||||||
|
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||||
|
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||||
|
the build system will package the resources for distribution and generate a class called
|
||||||
|
"Resource" that contains the tokens for each one of the resources included. For example,
|
||||||
|
for the above Resources layout, this is what the Resource class would expose:
|
||||||
|
|
||||||
|
public class Resource {
|
||||||
|
public class drawable {
|
||||||
|
public const int icon = 0x123;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class layout {
|
||||||
|
public const int main = 0x456;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class strings {
|
||||||
|
public const int first_string = 0xabc;
|
||||||
|
public const int second_string = 0xbcd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
|
||||||
|
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
|
||||||
|
string in the dictionary file values/strings.xml.
|
BIN
src/Kp2aUnitTests/Resources/Drawable/Icon.png
Normal file
BIN
src/Kp2aUnitTests/Resources/Drawable/Icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
13
src/Kp2aUnitTests/Resources/Layout/Main.axml
Normal file
13
src/Kp2aUnitTests/Resources/Layout/Main.axml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/MyButton"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/Hello"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
116
src/Kp2aUnitTests/Resources/Resource.Designer.cs
generated
Normal file
116
src/Kp2aUnitTests/Resources/Resource.Designer.cs
generated
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#pragma warning disable 1591
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Dieser Code wurde von einem Tool generiert.
|
||||||
|
// Laufzeitversion:4.0.30319.18046
|
||||||
|
//
|
||||||
|
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||||
|
// der Code erneut generiert wird.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[assembly: global::Android.Runtime.ResourceDesignerAttribute("Kp2aUnitTests.Resource", IsApplication=true)]
|
||||||
|
|
||||||
|
namespace Kp2aUnitTests
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
|
||||||
|
public partial class Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
static Resource()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateIdValues()
|
||||||
|
{
|
||||||
|
KeePassLib2Android.Resource.String.library_name = Kp2aUnitTests.Resource.String.library_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Attribute
|
||||||
|
{
|
||||||
|
|
||||||
|
static Attribute()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Attribute()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Drawable
|
||||||
|
{
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f020000
|
||||||
|
public const int Icon = 2130837504;
|
||||||
|
|
||||||
|
static Drawable()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Id
|
||||||
|
{
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f050000
|
||||||
|
public const int MyButton = 2131034112;
|
||||||
|
|
||||||
|
static Id()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Id()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Layout
|
||||||
|
{
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f030000
|
||||||
|
public const int Main = 2130903040;
|
||||||
|
|
||||||
|
static Layout()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Layout()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class String
|
||||||
|
{
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f040001
|
||||||
|
public const int ApplicationName = 2130968577;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f040000
|
||||||
|
public const int Hello = 2130968576;
|
||||||
|
|
||||||
|
// aapt resource value: 0x7f040002
|
||||||
|
public const int library_name = 2130968578;
|
||||||
|
|
||||||
|
static String()
|
||||||
|
{
|
||||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma warning restore 1591
|
5
src/Kp2aUnitTests/Resources/Values/Strings.xml
Normal file
5
src/Kp2aUnitTests/Resources/Values/Strings.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="Hello">Hello World, Click Me!</string>
|
||||||
|
<string name="ApplicationName">Kp2aUnitTests</string>
|
||||||
|
</resources>
|
51
src/Kp2aUnitTests/TestCreateDb.cs
Normal file
51
src/Kp2aUnitTests/TestCreateDb.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Android.App;
|
||||||
|
using Java.IO;
|
||||||
|
using KeePassLib;
|
||||||
|
using KeePassLib.Keys;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using keepass2android;
|
||||||
|
|
||||||
|
namespace Kp2aUnitTests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
class TestCreateDb
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void CreateAndSaveLocal()
|
||||||
|
{
|
||||||
|
IKp2aApp app = new TestKp2aApp();
|
||||||
|
IOConnectionInfo ioc = new IOConnectionInfo {Path = "/mnt/sdcard/kp2atest/savetest.kdbx"};
|
||||||
|
|
||||||
|
File outputDir = new File("/mnt/sdcard/kp2atest/");
|
||||||
|
outputDir.Mkdirs();
|
||||||
|
File targetFile = new File(ioc.Path);
|
||||||
|
if (targetFile.Exists())
|
||||||
|
targetFile.Delete();
|
||||||
|
|
||||||
|
bool createSuccesful = false;
|
||||||
|
//create the task:
|
||||||
|
CreateDb createDb = new CreateDb(app, Application.Context, ioc, new ActionOnFinish((success, message) =>
|
||||||
|
{ createSuccesful = success; if (!success)
|
||||||
|
Assert.Fail(message);
|
||||||
|
}), false);
|
||||||
|
//run it:
|
||||||
|
createDb.Run();
|
||||||
|
//check expectations:
|
||||||
|
Assert.IsTrue(createSuccesful);
|
||||||
|
Assert.IsNotNull(app.GetDb());
|
||||||
|
Assert.IsNotNull(app.GetDb().KpDatabase);
|
||||||
|
//the create task should create two groups:
|
||||||
|
Assert.AreEqual(2, app.GetDb().KpDatabase.RootGroup.Groups.Count());
|
||||||
|
|
||||||
|
//ensure the the database can be loaded from file:
|
||||||
|
PwDatabase loadedDb = new PwDatabase();
|
||||||
|
loadedDb.Open(ioc, new CompositeKey(), null);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/Kp2aUnitTests/TestDrawableFactory.cs
Normal file
27
src/Kp2aUnitTests/TestDrawableFactory.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
|
using Android.Widget;
|
||||||
|
using KeePassLib;
|
||||||
|
using keepass2android;
|
||||||
|
|
||||||
|
namespace Kp2aUnitTests
|
||||||
|
{
|
||||||
|
internal class TestDrawableFactory : IDrawableFactory
|
||||||
|
{
|
||||||
|
public void AssignDrawableTo(ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable GetIconDrawable(Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
||||||
|
{
|
||||||
|
return res.GetDrawable(Resource.Drawable.Icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
src/Kp2aUnitTests/TestKp2aApp.cs
Normal file
54
src/Kp2aUnitTests/TestKp2aApp.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using Android.Content;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
using keepass2android;
|
||||||
|
|
||||||
|
namespace Kp2aUnitTests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Very simple implementation of the Kp2aApp interface to be used in tests
|
||||||
|
/// </summary>
|
||||||
|
internal class TestKp2aApp : IKp2aApp
|
||||||
|
{
|
||||||
|
private Database _db;
|
||||||
|
|
||||||
|
public void SetShutdown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Database GetDb()
|
||||||
|
{
|
||||||
|
return _db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Database CreateNewDatabase()
|
||||||
|
{
|
||||||
|
TestDrawableFactory testDrawableFactory = new TestDrawableFactory();
|
||||||
|
_db = new Database(testDrawableFactory, new TestKp2aApp());
|
||||||
|
return _db;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetResourceString(UiStringKey stringKey)
|
||||||
|
{
|
||||||
|
return stringKey.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetBooleanPreference(PreferenceKey key)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey, EventHandler<DialogClickEventArgs> yesHandler, EventHandler<DialogClickEventArgs> noHandler,
|
||||||
|
EventHandler<DialogClickEventArgs> cancelHandler, Context ctx)
|
||||||
|
{
|
||||||
|
yesHandler(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,15 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
|
|
||||||
@ -41,15 +35,15 @@ namespace keepass2android
|
|||||||
SetContentView(Resource.Layout.about);
|
SetContentView(Resource.Layout.about);
|
||||||
SetTitle(Resource.String.app_name);
|
SetTitle(Resource.String.app_name);
|
||||||
|
|
||||||
setVersion();
|
SetVersion();
|
||||||
|
|
||||||
Button okButton = (Button) FindViewById(Resource.Id.about_button);
|
Button okButton = (Button) FindViewById(Resource.Id.about_button);
|
||||||
okButton.Click += (object sender, EventArgs e) => {
|
okButton.Click += (sender, e) => {
|
||||||
Dismiss();
|
Dismiss();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVersion() {
|
private void SetVersion() {
|
||||||
Context ctx = Context;
|
Context ctx = Context;
|
||||||
|
|
||||||
String version;
|
String version;
|
||||||
|
@ -14,7 +14,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using Android.App;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Util;
|
using Android.Util;
|
||||||
using Java.IO;
|
using Java.IO;
|
||||||
using Android.Net;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[ContentProvider(new string[]{"keepass2android."+AppNames.PackagePart+".provider"})]
|
/// <summary>
|
||||||
|
/// Makes attachments of PwEntries accessible when they are stored in the app cache
|
||||||
|
/// </summary>
|
||||||
|
[ContentProvider(new[]{"keepass2android."+AppNames.PackagePart+".provider"})]
|
||||||
public class AttachmentContentProvider : ContentProvider {
|
public class AttachmentContentProvider : ContentProvider {
|
||||||
|
|
||||||
private const String CLASS_NAME = "AttachmentContentProvider";
|
private const String ClassName = "AttachmentContentProvider";
|
||||||
|
|
||||||
// The authority is the symbolic name for the provider class
|
// The authority is the symbolic name for the provider class
|
||||||
public const String AUTHORITY = "keepass2android."+AppNames.PackagePart+".provider";
|
public const String Authority = "keepass2android."+AppNames.PackagePart+".provider";
|
||||||
|
|
||||||
|
|
||||||
public override bool OnCreate() {
|
public override bool OnCreate() {
|
||||||
@ -31,12 +25,12 @@ namespace keepass2android
|
|||||||
public override ParcelFileDescriptor OpenFile(Android.Net.Uri uri, String mode)
|
public override ParcelFileDescriptor OpenFile(Android.Net.Uri uri, String mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
String LOG_TAG = CLASS_NAME + " - openFile";
|
const string logTag = ClassName + " - openFile";
|
||||||
|
|
||||||
Log.Verbose(LOG_TAG,
|
Log.Verbose(logTag,
|
||||||
"Called with uri: '" + uri + "'." + uri.LastPathSegment);
|
"Called with uri: '" + uri + "'." + uri.LastPathSegment);
|
||||||
|
|
||||||
if (uri.ToString().StartsWith("content://" + AUTHORITY))
|
if (uri.ToString().StartsWith("content://" + Authority))
|
||||||
{
|
{
|
||||||
// The desired file name is specified by the last segment of the
|
// The desired file name is specified by the last segment of the
|
||||||
// path
|
// path
|
||||||
@ -54,12 +48,9 @@ namespace keepass2android
|
|||||||
return pfd;
|
return pfd;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
Log.Verbose(logTag, "Unsupported uri: '" + uri + "'.");
|
||||||
{
|
throw new FileNotFoundException("Unsupported uri: "
|
||||||
Log.Verbose(LOG_TAG, "Unsupported uri: '" + uri + "'.");
|
+ uri.ToString());
|
||||||
throw new FileNotFoundException("Unsupported uri: "
|
|
||||||
+ uri.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////
|
||||||
|
@ -15,36 +15,22 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class CancelDialog : Dialog {
|
public class CancelDialog : Dialog {
|
||||||
|
|
||||||
private bool mCanceled = false;
|
|
||||||
|
|
||||||
public CancelDialog(Context context): base(context) {
|
public CancelDialog(Context context): base(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool canceled() {
|
public bool Canceled { get; private set; }
|
||||||
return mCanceled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void Cancel() {
|
public override void Cancel() {
|
||||||
base.Cancel();
|
base.Cancel();
|
||||||
mCanceled = true;
|
Canceled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,288 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.Interfaces;
|
|
||||||
using KeePassLib.Serialization;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
|
|
||||||
public class Database {
|
|
||||||
|
|
||||||
|
|
||||||
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 pm;
|
|
||||||
public IOConnectionInfo mIoc;
|
|
||||||
public DateTime mLastChangeDate;
|
|
||||||
public SearchDbHelper searchHelper;
|
|
||||||
|
|
||||||
public DrawableFactory drawFactory = new DrawableFactory();
|
|
||||||
|
|
||||||
private bool loaded = false;
|
|
||||||
|
|
||||||
private bool mReloadRequested = false;
|
|
||||||
|
|
||||||
public bool Loaded {
|
|
||||||
get { return loaded;}
|
|
||||||
set { loaded = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Open
|
|
||||||
{
|
|
||||||
get { return Loaded && (!Locked); }
|
|
||||||
}
|
|
||||||
|
|
||||||
bool locked;
|
|
||||||
public bool Locked
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return locked;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
locked = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DidOpenFileChange()
|
|
||||||
{
|
|
||||||
if ((Loaded == false) || (mIoc.IsLocalFile() == false))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return System.IO.File.GetLastWriteTimeUtc(mIoc.Path) > mLastChangeDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckForOpenFileChanged(Activity activity)
|
|
||||||
{
|
|
||||||
if (DidOpenFileChange())
|
|
||||||
{
|
|
||||||
if (mReloadRequested)
|
|
||||||
{
|
|
||||||
|
|
||||||
activity.SetResult(KeePass.EXIT_RELOAD_DB);
|
|
||||||
activity.Finish();
|
|
||||||
}
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
|
||||||
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
|
|
||||||
|
|
||||||
builder.SetMessage(activity.GetString(Resource.String.AskReloadFile));
|
|
||||||
|
|
||||||
builder.SetPositiveButton(activity.GetString(Android.Resource.String.Yes), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
|
||||||
{
|
|
||||||
mReloadRequested = true;
|
|
||||||
activity.SetResult(KeePass.EXIT_RELOAD_DB);
|
|
||||||
activity.Finish();
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
|
||||||
{
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
|
||||||
dialog.Show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadData(Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status)
|
|
||||||
{
|
|
||||||
mIoc = iocInfo;
|
|
||||||
|
|
||||||
KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase();
|
|
||||||
|
|
||||||
KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey();
|
|
||||||
key.AddUserKey(new KeePassLib.Keys.KcpPassword(password));
|
|
||||||
if (!String.IsNullOrEmpty(keyfile))
|
|
||||||
{
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile));
|
|
||||||
} catch (Exception)
|
|
||||||
{
|
|
||||||
throw new KeyFileException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pwDatabase.Open(iocInfo, key, status);
|
|
||||||
|
|
||||||
if (iocInfo.IsLocalFile())
|
|
||||||
{
|
|
||||||
mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
mLastChangeDate = DateTime.MinValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
root = pwDatabase.RootGroup;
|
|
||||||
populateGlobals(root);
|
|
||||||
|
|
||||||
|
|
||||||
Loaded = true;
|
|
||||||
pm = pwDatabase;
|
|
||||||
searchHelper = new SearchDbHelper(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool quickUnlockEnabled = false;
|
|
||||||
public bool QuickUnlockEnabled
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return quickUnlockEnabled;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
quickUnlockEnabled = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//KeyLength of QuickUnlock at time of loading the database.
|
|
||||||
//This is important to not allow an attacker to set the length to 1 when QuickUnlock is started already.
|
|
||||||
public int QuickUnlockKeyLength
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PwGroup SearchForText(String str) {
|
|
||||||
PwGroup group = searchHelper.searchForText(this, str);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public PwGroup Search(SearchParameters searchParams)
|
|
||||||
{
|
|
||||||
return Search(searchParams, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PwGroup Search(SearchParameters searchParams, IDictionary<PwUuid, String> resultContexts)
|
|
||||||
{
|
|
||||||
return searchHelper.search(this, searchParams, resultContexts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PwGroup SearchForExactUrl(String url) {
|
|
||||||
PwGroup group = searchHelper.searchForExactUrl(this, url);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
|
||||||
PwGroup group = searchHelper.searchForHost(this, url, allowSubdomains);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void SaveData(Context ctx) {
|
|
||||||
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(ctx);
|
|
||||||
pm.UseFileTransactions = prefs.GetBoolean(ctx.GetString(Resource.String.UseFileTransactions_key), true);
|
|
||||||
pm.Save(null);
|
|
||||||
|
|
||||||
}
|
|
||||||
class SaveStatusLogger: IStatusLogger
|
|
||||||
{
|
|
||||||
#region IStatusLogger implementation
|
|
||||||
public void StartLogging (string strOperation, bool bWriteOperationToLog)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public void EndLogging ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public bool SetProgress (uint uPercent)
|
|
||||||
{
|
|
||||||
Android.Util.Log.Debug("DEBUG", "Progress: " + uPercent+"%");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public bool SetText (string strNewText, LogStatusType lsType)
|
|
||||||
{
|
|
||||||
Android.Util.Log.Debug("DEBUG", strNewText);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public bool ContinueWork ()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateGlobals (PwGroup currentGroup)
|
|
||||||
{
|
|
||||||
|
|
||||||
var childGroups = currentGroup.Groups;
|
|
||||||
var childEntries = currentGroup.Entries;
|
|
||||||
|
|
||||||
foreach (PwEntry e in childEntries) {
|
|
||||||
entries [e.Uuid] = e;
|
|
||||||
}
|
|
||||||
foreach (PwGroup g in childGroups) {
|
|
||||||
groups[g.Uuid] = g;
|
|
||||||
populateGlobals(g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear() {
|
|
||||||
groups.Clear();
|
|
||||||
entries.Clear();
|
|
||||||
dirty.Clear();
|
|
||||||
drawFactory.Clear();
|
|
||||||
|
|
||||||
root = null;
|
|
||||||
pm = null;
|
|
||||||
mIoc = null;
|
|
||||||
loaded = false;
|
|
||||||
locked = false;
|
|
||||||
mReloadRequested = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markAllGroupsAsDirty() {
|
|
||||||
foreach ( PwGroup group in groups.Values ) {
|
|
||||||
dirty.Add(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -17,26 +17,20 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using Android.Text.Format;
|
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
using Java.Util;
|
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using Android.Text.Method;
|
using Android.Text.Method;
|
||||||
using Android.Util;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using KeePassLib.Security;
|
using KeePassLib.Security;
|
||||||
using keepass2android.view;
|
|
||||||
using Android.Webkit;
|
using Android.Webkit;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using Java.IO;
|
using Java.IO;
|
||||||
@ -45,41 +39,39 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
||||||
public class EntryActivity : LockCloseActivity {
|
public class EntryActivity : LockCloseActivity {
|
||||||
public const String KEY_ENTRY = "entry";
|
public const String KeyEntry = "entry";
|
||||||
public const String KEY_REFRESH_POS = "refresh_pos";
|
public const String KeyRefreshPos = "refresh_pos";
|
||||||
public const String KEY_CLOSE_AFTER_CREATE = "close_after_create";
|
public const String KeyCloseAfterCreate = "close_after_create";
|
||||||
|
|
||||||
|
|
||||||
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask) {
|
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask) {
|
||||||
Intent i;
|
Intent i = new Intent(act, typeof(EntryActivity));
|
||||||
|
|
||||||
i = new Intent(act, typeof(EntryActivity));
|
|
||||||
|
|
||||||
|
|
||||||
i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString());
|
i.PutExtra(KeyEntry, pw.Uuid.ToHexString());
|
||||||
i.PutExtra(KEY_REFRESH_POS, pos);
|
i.PutExtra(KeyRefreshPos, pos);
|
||||||
|
|
||||||
appTask.ToIntent(i);
|
appTask.ToIntent(i);
|
||||||
|
|
||||||
act.StartActivityForResult(i,0);
|
act.StartActivityForResult(i,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PwEntry mEntry;
|
protected PwEntry Entry;
|
||||||
|
|
||||||
private bool mShowPassword;
|
private bool _showPassword;
|
||||||
private int mPos;
|
private int _pos;
|
||||||
|
|
||||||
AppTask mAppTask;
|
AppTask _appTask;
|
||||||
|
|
||||||
|
|
||||||
protected void setEntryView() {
|
protected void SetEntryView() {
|
||||||
SetContentView(Resource.Layout.entry_view);
|
SetContentView(Resource.Layout.entry_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupEditButtons() {
|
protected void SetupEditButtons() {
|
||||||
View edit = FindViewById(Resource.Id.entry_edit);
|
View edit = FindViewById(Resource.Id.entry_edit);
|
||||||
edit.Click += (sender, e) => {
|
edit.Click += (sender, e) => {
|
||||||
EntryEditActivity.Launch(this, mEntry,mAppTask);
|
EntryEditActivity.Launch(this, Entry,_appTask);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,17 +83,14 @@ namespace keepass2android
|
|||||||
|
|
||||||
ISharedPreferencesEditor edit = prefs.Edit();
|
ISharedPreferencesEditor edit = prefs.Edit();
|
||||||
edit.PutLong(GetString(Resource.String.UsageCount_key), usageCount+1);
|
edit.PutLong(GetString(Resource.String.UsageCount_key), usageCount+1);
|
||||||
EditorCompat.apply(edit);
|
EditorCompat.Apply(edit);
|
||||||
|
|
||||||
mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
_showPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||||
|
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
setEntryView();
|
SetEntryView();
|
||||||
|
|
||||||
Context appCtx = ApplicationContext;
|
|
||||||
|
|
||||||
|
Database db = App.Kp2a.GetDb();
|
||||||
Database db = App.getDB();
|
|
||||||
// Likely the app has been killed exit the activity
|
// Likely the app has been killed exit the activity
|
||||||
if (! db.Loaded)
|
if (! db.Loaded)
|
||||||
{
|
{
|
||||||
@ -109,77 +98,62 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResult(KeePass.EXIT_NORMAL);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
Intent i = Intent;
|
Intent i = Intent;
|
||||||
PwUuid uuid = new PwUuid(MemUtil.HexStringToByteArray(i.GetStringExtra(KEY_ENTRY)));
|
PwUuid uuid = new PwUuid(MemUtil.HexStringToByteArray(i.GetStringExtra(KeyEntry)));
|
||||||
mPos = i.GetIntExtra(KEY_REFRESH_POS, -1);
|
_pos = i.GetIntExtra(KeyRefreshPos, -1);
|
||||||
|
|
||||||
mAppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
_appTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||||
|
|
||||||
bool closeAfterCreate = mAppTask.CloseEntryActivityAfterCreate;
|
bool closeAfterCreate = _appTask.CloseEntryActivityAfterCreate;
|
||||||
|
|
||||||
mEntry = db.entries [uuid];
|
Entry = db.Entries [uuid];
|
||||||
|
|
||||||
// Refresh Menu contents in case onCreateMenuOptions was called before mEntry was set
|
// Refresh Menu contents in case onCreateMenuOptions was called before _entry was set
|
||||||
ActivityCompat.invalidateOptionsMenu(this);
|
ActivityCompat.InvalidateOptionsMenu(this);
|
||||||
|
|
||||||
// Update last access time.
|
// Update last access time.
|
||||||
mEntry.Touch(false);
|
Entry.Touch(false);
|
||||||
|
|
||||||
if (PwDefs.IsTanEntry(mEntry) && prefs.GetBoolean(GetString(Resource.String.TanExpiresOnUse_key), Resources.GetBoolean(Resource.Boolean.TanExpiresOnUse_default)) && ((mEntry.Expires == false) || mEntry.ExpiryTime > DateTime.Now))
|
if (PwDefs.IsTanEntry(Entry) && prefs.GetBoolean(GetString(Resource.String.TanExpiresOnUse_key), Resources.GetBoolean(Resource.Boolean.TanExpiresOnUse_default)) && ((Entry.Expires == false) || Entry.ExpiryTime > DateTime.Now))
|
||||||
{
|
{
|
||||||
PwEntry backupEntry = mEntry.CloneDeep();
|
PwEntry backupEntry = Entry.CloneDeep();
|
||||||
mEntry.ExpiryTime = DateTime.Now;
|
Entry.ExpiryTime = DateTime.Now;
|
||||||
mEntry.Expires = true;
|
Entry.Expires = true;
|
||||||
mEntry.Touch(true);
|
Entry.Touch(true);
|
||||||
requiresRefresh();
|
RequiresRefresh();
|
||||||
Handler handler = new Handler();
|
UpdateEntry update = new UpdateEntry(this, App.Kp2a.GetDb(), backupEntry, Entry, null);
|
||||||
UpdateEntry update = new UpdateEntry(this, App.getDB(), backupEntry, mEntry, new AfterSave(handler));
|
ProgressTask pt = new ProgressTask(App.Kp2a, this, update, UiStringKey.saving_database);
|
||||||
ProgressTask pt = new ProgressTask(this, update, Resource.String.saving_database);
|
pt.Run();
|
||||||
pt.run();
|
|
||||||
}
|
}
|
||||||
fillData(false);
|
FillData(false);
|
||||||
|
|
||||||
setupEditButtons();
|
SetupEditButtons();
|
||||||
|
|
||||||
Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService));
|
Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService));
|
||||||
Intent.SetAction(Intents.SHOW_NOTIFICATION);
|
Intent.SetAction(Intents.ShowNotification);
|
||||||
showNotIntent.PutExtra(KEY_ENTRY, mEntry.Uuid.ToHexString());
|
showNotIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
|
||||||
showNotIntent.PutExtra(KEY_CLOSE_AFTER_CREATE, closeAfterCreate);
|
showNotIntent.PutExtra(KeyCloseAfterCreate, closeAfterCreate);
|
||||||
|
|
||||||
StartService(showNotIntent);
|
StartService(showNotIntent);
|
||||||
|
|
||||||
Android.Util.Log.Debug("DEBUG", "Requesting copy to clipboard for Uuid=" + mEntry.Uuid.ToHexString());
|
Android.Util.Log.Debug("DEBUG", "Requesting copy to clipboard for Uuid=" + Entry.Uuid.ToHexString());
|
||||||
|
|
||||||
/*foreach (PwUuid key in App.getDB().entries.Keys)
|
/*foreach (PwUuid key in App.Kp2a.GetDb().entries.Keys)
|
||||||
{
|
{
|
||||||
Android.Util.Log.Debug("DEBUG",key.ToHexString() + " -> " + App.getDB().entries[key].Uuid.ToHexString());
|
Android.Util.Log.Debug("DEBUG",key.ToHexString() + " -> " + App.Kp2a.GetDb().entries[key].Uuid.ToHexString());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (closeAfterCreate)
|
if (closeAfterCreate)
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE);
|
SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterSave : OnFinish {
|
|
||||||
|
|
||||||
public AfterSave(Handler handler):base(handler) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void run() {
|
|
||||||
|
|
||||||
base.run();
|
private String getDateTime(DateTime dt) {
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String getDateTime(System.DateTime dt) {
|
|
||||||
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +170,7 @@ namespace keepass2android
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateExtraStrings(bool trimList)
|
void PopulateExtraStrings(bool trimList)
|
||||||
{
|
{
|
||||||
ViewGroup extraGroup = (ViewGroup)FindViewById(Resource.Id.extra_strings);
|
ViewGroup extraGroup = (ViewGroup)FindViewById(Resource.Id.extra_strings);
|
||||||
if (trimList)
|
if (trimList)
|
||||||
@ -204,7 +178,7 @@ namespace keepass2android
|
|||||||
extraGroup.RemoveAllViews();
|
extraGroup.RemoveAllViews();
|
||||||
}
|
}
|
||||||
bool hasExtraFields = false;
|
bool hasExtraFields = false;
|
||||||
foreach (var view in from pair in mEntry.Strings where !PwDefs.IsStandardField(pair.Key) orderby pair.Key
|
foreach (var view in from pair in Entry.Strings where !PwDefs.IsStandardField(pair.Key) orderby pair.Key
|
||||||
select CreateEditSection(pair.Key, pair.Value.ReadString()))
|
select CreateEditSection(pair.Key, pair.Value.ReadString()))
|
||||||
{
|
{
|
||||||
//View view = new EntrySection(this, null, key, pair.Value.ReadString());
|
//View view = new EntrySection(this, null, key, pair.Value.ReadString());
|
||||||
@ -216,9 +190,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
View CreateEditSection(string key, string value)
|
View CreateEditSection(string key, string value)
|
||||||
{
|
{
|
||||||
LinearLayout layout = new LinearLayout(this, null);
|
LinearLayout layout = new LinearLayout(this, null) {Orientation = Orientation.Vertical};
|
||||||
layout.Orientation = Orientation.Vertical;
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
|
||||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FillParent, LinearLayout.LayoutParams.WrapContent);
|
|
||||||
layoutParams.SetMargins(10,0,0,0);
|
layoutParams.SetMargins(10,0,0,0);
|
||||||
layout.LayoutParameters = layoutParams;
|
layout.LayoutParameters = layoutParams;
|
||||||
View viewInflated = LayoutInflater.Inflate(Resource.Layout.entry_extrastring_title,null);
|
View viewInflated = LayoutInflater.Inflate(Resource.Layout.entry_extrastring_title,null);
|
||||||
@ -232,15 +205,15 @@ namespace keepass2android
|
|||||||
valueView.Text = value;
|
valueView.Text = value;
|
||||||
valueView.Typeface = Typeface.Monospace;
|
valueView.Typeface = Typeface.Monospace;
|
||||||
|
|
||||||
if ((int)Android.OS.Build.VERSION.SdkInt >= 11)
|
if ((int)Build.VERSION.SdkInt >= 11)
|
||||||
valueView.SetTextIsSelectable(true);
|
valueView.SetTextIsSelectable(true);
|
||||||
layout.AddView(valueView);
|
layout.AddView(valueView);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
Android.Net.Uri writeBinaryToFile(string key, bool writeToCacheDirectory)
|
Android.Net.Uri WriteBinaryToFile(string key, bool writeToCacheDirectory)
|
||||||
{
|
{
|
||||||
ProtectedBinary pb = mEntry.Binaries.Get(key);
|
ProtectedBinary pb = Entry.Binaries.Get(key);
|
||||||
System.Diagnostics.Debug.Assert(pb != null);
|
System.Diagnostics.Debug.Assert(pb != null);
|
||||||
if (pb == null)
|
if (pb == null)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
@ -253,9 +226,9 @@ namespace keepass2android
|
|||||||
string filepart = key;
|
string filepart = key;
|
||||||
if (writeToCacheDirectory)
|
if (writeToCacheDirectory)
|
||||||
filepart = filepart.Replace(" ", "");
|
filepart = filepart.Replace(" ", "");
|
||||||
var targetFile = new Java.IO.File(binaryDirectory, filepart);
|
var targetFile = new File(binaryDirectory, filepart);
|
||||||
|
|
||||||
Java.IO.File parent = targetFile.ParentFile;
|
File parent = targetFile.ParentFile;
|
||||||
|
|
||||||
if (parent == null || (parent.Exists() && ! parent.IsDirectory))
|
if (parent == null || (parent.Exists() && ! parent.IsDirectory))
|
||||||
{
|
{
|
||||||
@ -296,29 +269,25 @@ namespace keepass2android
|
|||||||
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[]{filename}), ToastLength.Short).Show();
|
Toast.MakeText(this, GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[]{filename}), ToastLength.Short).Show();
|
||||||
if (writeToCacheDirectory)
|
if (writeToCacheDirectory)
|
||||||
{
|
{
|
||||||
return Android.Net.Uri.Parse("content://" + AttachmentContentProvider.AUTHORITY + "/"
|
return Android.Net.Uri.Parse("content://" + AttachmentContentProvider.Authority + "/"
|
||||||
+ filename);
|
+ filename);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return fileUri;
|
return fileUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
void OpenBinaryFile(Android.Net.Uri uri)
|
||||||
|
|
||||||
void openBinaryFile(Android.Net.Uri uri)
|
|
||||||
{
|
{
|
||||||
String theMIMEType = getMimeType(uri.Path);
|
String theMimeType = GetMimeType(uri.Path);
|
||||||
if (theMIMEType != null)
|
if (theMimeType != null)
|
||||||
{
|
{
|
||||||
Intent theIntent = new Intent(Intent.ActionView);
|
Intent theIntent = new Intent(Intent.ActionView);
|
||||||
theIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
theIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ExcludeFromRecents);
|
||||||
theIntent.SetDataAndType(uri, theMIMEType);
|
theIntent.SetDataAndType(uri, theMimeType);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StartActivity(theIntent);
|
StartActivity(theIntent);
|
||||||
}
|
}
|
||||||
catch (ActivityNotFoundException anfe)
|
catch (ActivityNotFoundException)
|
||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
Toast.MakeText(this, "Couldn't open file", ToastLength.Short).Show();
|
Toast.MakeText(this, "Couldn't open file", ToastLength.Short).Show();
|
||||||
@ -326,21 +295,21 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateBinaries(bool trimList)
|
void PopulateBinaries(bool trimList)
|
||||||
{
|
{
|
||||||
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
||||||
if (trimList)
|
if (trimList)
|
||||||
{
|
{
|
||||||
binariesGroup.RemoveAllViews();
|
binariesGroup.RemoveAllViews();
|
||||||
}
|
}
|
||||||
foreach (KeyValuePair<string, ProtectedBinary> pair in mEntry.Binaries)
|
foreach (KeyValuePair<string, ProtectedBinary> pair in Entry.Binaries)
|
||||||
{
|
{
|
||||||
String key = pair.Key;
|
String key = pair.Key;
|
||||||
Button binaryButton = new Button(this);
|
Button binaryButton = new Button(this);
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent);
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
|
||||||
binaryButton.Text = key;
|
binaryButton.Text = key;
|
||||||
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuSave),null, null, null);
|
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuSave),null, null, null);
|
||||||
binaryButton.Click += (object sender, EventArgs e) =>
|
binaryButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
Button btnSender = (Button)(sender);
|
Button btnSender = (Button)(sender);
|
||||||
|
|
||||||
@ -349,19 +318,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
builder.SetMessage(GetString(Resource.String.SaveAttachmentDialog_text));
|
builder.SetMessage(GetString(Resource.String.SaveAttachmentDialog_text));
|
||||||
|
|
||||||
builder.SetPositiveButton(GetString(Resource.String.SaveAttachmentDialog_save), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetPositiveButton(GetString(Resource.String.SaveAttachmentDialog_save), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
writeBinaryToFile(btnSender.Text, false);
|
WriteBinaryToFile(btnSender.Text, false);
|
||||||
}));
|
});
|
||||||
|
|
||||||
builder.SetNegativeButton(GetString(Resource.String.SaveAttachmentDialog_open), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetNegativeButton(GetString(Resource.String.SaveAttachmentDialog_open), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
Android.Net.Uri newUri = writeBinaryToFile(btnSender.Text, true);
|
Android.Net.Uri newUri = WriteBinaryToFile(btnSender.Text, true);
|
||||||
if (newUri != null)
|
if (newUri != null)
|
||||||
{
|
{
|
||||||
openBinaryFile(newUri);
|
OpenBinaryFile(newUri);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
@ -372,11 +341,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
FindViewById(Resource.Id.entry_binaries_label).Visibility = mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
FindViewById(Resource.Id.entry_binaries_label).Visibility = Entry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||||
}
|
}
|
||||||
|
|
||||||
// url = file path or whatever suitable URL you want.
|
// url = file path or whatever suitable URL you want.
|
||||||
public static String getMimeType(String url)
|
public static String GetMimeType(String url)
|
||||||
{
|
{
|
||||||
String type = null;
|
String type = null;
|
||||||
String extension = MimeTypeMap.GetFileExtensionFromUrl(url);
|
String extension = MimeTypeMap.GetFileExtensionFromUrl(url);
|
||||||
@ -393,58 +362,58 @@ namespace keepass2android
|
|||||||
OverridePendingTransition(Resource.Animation.anim_enter_back, Resource.Animation.anim_leave_back);
|
OverridePendingTransition(Resource.Animation.anim_enter_back, Resource.Animation.anim_leave_back);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fillData(bool trimList)
|
protected void FillData(bool trimList)
|
||||||
{
|
{
|
||||||
ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon);
|
ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon);
|
||||||
if (iv != null)
|
if (iv != null)
|
||||||
{
|
{
|
||||||
App.getDB().drawFactory.assignDrawableTo(iv, Resources, App.getDB().pm, mEntry.IconId, mEntry.CustomIconUuid);
|
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, Entry.IconId, Entry.CustomIconUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
//populateText(Resource.Id.entry_title, mEntry.Strings.ReadSafe(PwDefs.TitleField));
|
//populateText(Resource.Id.entry_title, _entry.Strings.ReadSafe(PwDefs.TitleField));
|
||||||
var button = ((Button)FindViewById(Resource.Id.entry_title));
|
var button = ((Button)FindViewById(Resource.Id.entry_title));
|
||||||
if (button != null)
|
if (button != null)
|
||||||
{
|
{
|
||||||
button.Text = mEntry.Strings.ReadSafe(PwDefs.TitleField);
|
button.Text = Entry.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
button.Click += (object sender, EventArgs e) => {
|
button.Click += (sender, e) => {
|
||||||
Finish(); };
|
Finish(); };
|
||||||
}
|
}
|
||||||
if (Util.HasActionBar(this))
|
if (Util.HasActionBar(this))
|
||||||
{
|
{
|
||||||
ActionBar.Title = mEntry.Strings.ReadSafe(PwDefs.TitleField);
|
ActionBar.Title = Entry.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
ActionBar.SetDisplayHomeAsUpEnabled(true);
|
ActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
populateText(Resource.Id.entry_user_name, Resource.Id.entry_user_name_label, mEntry.Strings.ReadSafe(PwDefs.UserNameField));
|
PopulateText(Resource.Id.entry_user_name, Resource.Id.entry_user_name_label, Entry.Strings.ReadSafe(PwDefs.UserNameField));
|
||||||
|
|
||||||
populateText(Resource.Id.entry_url, Resource.Id.entry_url_label, mEntry.Strings.ReadSafe(PwDefs.UrlField));
|
PopulateText(Resource.Id.entry_url, Resource.Id.entry_url_label, Entry.Strings.ReadSafe(PwDefs.UrlField));
|
||||||
populateText(Resource.Id.entry_password, Resource.Id.entry_password_label, mEntry.Strings.ReadSafe(PwDefs.PasswordField));
|
PopulateText(Resource.Id.entry_password, Resource.Id.entry_password_label, Entry.Strings.ReadSafe(PwDefs.PasswordField));
|
||||||
setPasswordStyle();
|
SetPasswordStyle();
|
||||||
|
|
||||||
populateText(Resource.Id.entry_created, Resource.Id.entry_created_label, getDateTime(mEntry.CreationTime));
|
PopulateText(Resource.Id.entry_created, Resource.Id.entry_created_label, getDateTime(Entry.CreationTime));
|
||||||
populateText(Resource.Id.entry_modified, Resource.Id.entry_modified_label, getDateTime(mEntry.LastModificationTime));
|
PopulateText(Resource.Id.entry_modified, Resource.Id.entry_modified_label, getDateTime(Entry.LastModificationTime));
|
||||||
populateText(Resource.Id.entry_accessed, Resource.Id.entry_accessed_label, getDateTime(mEntry.LastAccessTime));
|
PopulateText(Resource.Id.entry_accessed, Resource.Id.entry_accessed_label, getDateTime(Entry.LastAccessTime));
|
||||||
|
|
||||||
if (mEntry.Expires)
|
if (Entry.Expires)
|
||||||
{
|
{
|
||||||
populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, getDateTime(mEntry.ExpiryTime));
|
PopulateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, getDateTime(Entry.ExpiryTime));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
populateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, Resource.String.never);
|
PopulateText(Resource.Id.entry_expires, Resource.Id.entry_expires_label, Resource.String.never);
|
||||||
}
|
}
|
||||||
populateText(Resource.Id.entry_comment, Resource.Id.entry_comment_label, mEntry.Strings.ReadSafe(PwDefs.NotesField));
|
PopulateText(Resource.Id.entry_comment, Resource.Id.entry_comment_label, Entry.Strings.ReadSafe(PwDefs.NotesField));
|
||||||
|
|
||||||
populateText(Resource.Id.entry_tags, Resource.Id.entry_tags_label, concatTags(mEntry.Tags));
|
PopulateText(Resource.Id.entry_tags, Resource.Id.entry_tags_label, concatTags(Entry.Tags));
|
||||||
|
|
||||||
populateText(Resource.Id.entry_override_url, Resource.Id.entry_override_url_label, mEntry.OverrideUrl);
|
PopulateText(Resource.Id.entry_override_url, Resource.Id.entry_override_url_label, Entry.OverrideUrl);
|
||||||
|
|
||||||
populateExtraStrings(trimList);
|
PopulateExtraStrings(trimList);
|
||||||
|
|
||||||
populateBinaries(trimList);
|
PopulateBinaries(trimList);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateText(int viewId, int headerViewId,int resId) {
|
private void PopulateText(int viewId, int headerViewId,int resId) {
|
||||||
View header = FindViewById(headerViewId);
|
View header = FindViewById(headerViewId);
|
||||||
TextView tv = (TextView)FindViewById(viewId);
|
TextView tv = (TextView)FindViewById(viewId);
|
||||||
|
|
||||||
@ -452,7 +421,7 @@ namespace keepass2android
|
|||||||
tv.SetText (resId);
|
tv.SetText (resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateText(int viewId, int headerViewId, String text)
|
private void PopulateText(int viewId, int headerViewId, String text)
|
||||||
{
|
{
|
||||||
View header = FindViewById(headerViewId);
|
View header = FindViewById(headerViewId);
|
||||||
TextView tv = (TextView)FindViewById(viewId);
|
TextView tv = (TextView)FindViewById(viewId);
|
||||||
@ -468,19 +437,19 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void requiresRefresh ()
|
void RequiresRefresh ()
|
||||||
{
|
{
|
||||||
Intent ret = new Intent ();
|
Intent ret = new Intent ();
|
||||||
ret.PutExtra (KEY_REFRESH_POS, mPos);
|
ret.PutExtra (KeyRefreshPos, _pos);
|
||||||
SetResult (KeePass.EXIT_REFRESH, ret);
|
SetResult (KeePass.ExitRefresh, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
if ( resultCode == KeePass.EXIT_REFRESH || resultCode == KeePass.EXIT_REFRESH_TITLE ) {
|
if ( resultCode == KeePass.ExitRefresh || resultCode == KeePass.ExitRefreshTitle ) {
|
||||||
fillData(true);
|
FillData(true);
|
||||||
if ( resultCode == KeePass.EXIT_REFRESH_TITLE ) {
|
if ( resultCode == KeePass.ExitRefreshTitle ) {
|
||||||
requiresRefresh ();
|
RequiresRefresh ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,7 +461,7 @@ namespace keepass2android
|
|||||||
inflater.Inflate(Resource.Menu.entry, menu);
|
inflater.Inflate(Resource.Menu.entry, menu);
|
||||||
|
|
||||||
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||||
if ( mShowPassword ) {
|
if ( _showPassword ) {
|
||||||
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
||||||
} else {
|
} else {
|
||||||
togglePassword.SetTitle(Resource.String.show_password);
|
togglePassword.SetTitle(Resource.String.show_password);
|
||||||
@ -503,23 +472,23 @@ namespace keepass2android
|
|||||||
//Disabled IMenuItem copyPass = menu.FindItem(Resource.Id.menu_copy_pass);
|
//Disabled IMenuItem copyPass = menu.FindItem(Resource.Id.menu_copy_pass);
|
||||||
|
|
||||||
// In API >= 11 onCreateOptionsMenu may be called before onCreate completes
|
// In API >= 11 onCreateOptionsMenu may be called before onCreate completes
|
||||||
// so mEntry may not be set
|
// so _entry may not be set
|
||||||
if (mEntry == null) {
|
if (Entry == null) {
|
||||||
gotoUrl.SetVisible(false);
|
gotoUrl.SetVisible(false);
|
||||||
//Disabled copyUser.SetVisible(false);
|
//Disabled copyUser.SetVisible(false);
|
||||||
//Disabled copyPass.SetVisible(false);
|
//Disabled copyPass.SetVisible(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String url = mEntry.Strings.ReadSafe (PwDefs.UrlField);
|
String url = Entry.Strings.ReadSafe (PwDefs.UrlField);
|
||||||
if (String.IsNullOrEmpty(url)) {
|
if (String.IsNullOrEmpty(url)) {
|
||||||
// disable button if url is not available
|
// disable button if url is not available
|
||||||
gotoUrl.SetVisible(false);
|
gotoUrl.SetVisible(false);
|
||||||
}
|
}
|
||||||
if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.UserNameField ))) {
|
if ( String.IsNullOrEmpty(Entry.Strings.ReadSafe(PwDefs.UserNameField ))) {
|
||||||
// disable button if username is not available
|
// disable button if username is not available
|
||||||
//Disabled copyUser.SetVisible(false);
|
//Disabled copyUser.SetVisible(false);
|
||||||
}
|
}
|
||||||
if ( String.IsNullOrEmpty(mEntry.Strings.ReadSafe(PwDefs.PasswordField ))) {
|
if ( String.IsNullOrEmpty(Entry.Strings.ReadSafe(PwDefs.PasswordField ))) {
|
||||||
// disable button if password is not available
|
// disable button if password is not available
|
||||||
//Disabled copyPass.SetVisible(false);
|
//Disabled copyPass.SetVisible(false);
|
||||||
}
|
}
|
||||||
@ -527,10 +496,10 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPasswordStyle() {
|
private void SetPasswordStyle() {
|
||||||
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
||||||
|
|
||||||
if ( mShowPassword ) {
|
if ( _showPassword ) {
|
||||||
password.TransformationMethod = null;
|
password.TransformationMethod = null;
|
||||||
} else {
|
} else {
|
||||||
password.TransformationMethod = PasswordTransformationMethod.Instance;
|
password.TransformationMethod = PasswordTransformationMethod.Instance;
|
||||||
@ -546,18 +515,18 @@ namespace keepass2android
|
|||||||
try {
|
try {
|
||||||
File dir = CacheDir;
|
File dir = CacheDir;
|
||||||
if (dir != null && dir.IsDirectory) {
|
if (dir != null && dir.IsDirectory) {
|
||||||
deleteDir(dir);
|
DeleteDir(dir);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool deleteDir(File dir) {
|
public static bool DeleteDir(File dir) {
|
||||||
if (dir != null && dir.IsDirectory) {
|
if (dir != null && dir.IsDirectory) {
|
||||||
String[] children = dir.List();
|
String[] children = dir.List();
|
||||||
for (int i = 0; i < children.Length; i++) {
|
for (int i = 0; i < children.Length; i++) {
|
||||||
bool success = deleteDir(new File(dir, children[i]));
|
bool success = DeleteDir(new File(dir, children[i]));
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -580,20 +549,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_toggle_pass:
|
case Resource.Id.menu_toggle_pass:
|
||||||
if ( mShowPassword ) {
|
if ( _showPassword ) {
|
||||||
item.SetTitle(Resource.String.show_password);
|
item.SetTitle(Resource.String.show_password);
|
||||||
mShowPassword = false;
|
_showPassword = false;
|
||||||
} else {
|
} else {
|
||||||
item.SetTitle(Resource.String.menu_hide_password);
|
item.SetTitle(Resource.String.menu_hide_password);
|
||||||
mShowPassword = true;
|
_showPassword = true;
|
||||||
}
|
}
|
||||||
setPasswordStyle();
|
SetPasswordStyle();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_goto_url:
|
case Resource.Id.menu_goto_url:
|
||||||
String url;
|
string url = Entry.Strings.ReadSafe (PwDefs.UrlField);
|
||||||
url = mEntry.Strings.ReadSafe (PwDefs.UrlField);
|
|
||||||
|
|
||||||
// Default http:// if no protocol specified
|
// Default http:// if no protocol specified
|
||||||
if ( ! url.Contains("://") ) {
|
if ( ! url.Contains("://") ) {
|
||||||
@ -608,11 +576,11 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
/* TODO: required?
|
/* TODO: required?
|
||||||
case Resource.Id.menu_copy_user:
|
case Resource.Id.menu_copy_user:
|
||||||
timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
timeoutCopyToClipboard(_entry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_copy_pass:
|
case Resource.Id.menu_copy_pass:
|
||||||
timeoutCopyToClipboard(mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
timeoutCopyToClipboard(_entry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||||
return true;
|
return true;
|
||||||
*/
|
*/
|
||||||
case Resource.Id.menu_rate:
|
case Resource.Id.menu_rate:
|
||||||
@ -630,8 +598,8 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_lock:
|
case Resource.Id.menu_lock:
|
||||||
App.setShutdown();
|
App.Kp2a.SetShutdown();
|
||||||
SetResult(KeePass.EXIT_LOCK);
|
SetResult(KeePass.ExitLock);
|
||||||
Finish();
|
Finish();
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_translate:
|
case Resource.Id.menu_translate:
|
||||||
|
@ -17,13 +17,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
@ -32,7 +28,6 @@ using KeePassLib;
|
|||||||
using Android.Text;
|
using Android.Text;
|
||||||
using KeePassLib.Security;
|
using KeePassLib.Security;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using keepass2android.view;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
@ -40,23 +35,23 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
||||||
public class EntryEditActivity : LockCloseActivity {
|
public class EntryEditActivity : LockCloseActivity {
|
||||||
public const String KEY_ENTRY = "entry";
|
public const String KeyEntry = "entry";
|
||||||
public const String KEY_PARENT = "parent";
|
public const String KeyParent = "parent";
|
||||||
|
|
||||||
public const int RESULT_OK_ICON_PICKER = (int)Result.FirstUser + 1000;
|
public const int ResultOkIconPicker = (int)Result.FirstUser + 1000;
|
||||||
public const int RESULT_OK_PASSWORD_GENERATOR = RESULT_OK_ICON_PICKER + 1;
|
public const int ResultOkPasswordGenerator = ResultOkIconPicker + 1;
|
||||||
|
|
||||||
const string Intent_ContinueWithEditing = "ContinueWithEditing";
|
const string IntentContinueWithEditing = "ContinueWithEditing";
|
||||||
|
|
||||||
EntryEditActivityState State
|
EntryEditActivityState State
|
||||||
{
|
{
|
||||||
get { return App.entryEditActivityState; }
|
get { return App.Kp2a.EntryEditActivityState; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Launch(Activity act, PwEntry pw, AppTask appTask) {
|
public static void Launch(Activity act, PwEntry pw, AppTask appTask) {
|
||||||
Intent i = new Intent(act, typeof(EntryEditActivity));
|
Intent i = new Intent(act, typeof(EntryEditActivity));
|
||||||
|
|
||||||
i.PutExtra(KEY_ENTRY, pw.Uuid.ToHexString());
|
i.PutExtra(KeyEntry, pw.Uuid.ToHexString());
|
||||||
|
|
||||||
appTask.ToIntent(i);
|
appTask.ToIntent(i);
|
||||||
|
|
||||||
@ -67,38 +62,36 @@ namespace keepass2android
|
|||||||
Intent i = new Intent(act, typeof(EntryEditActivity));
|
Intent i = new Intent(act, typeof(EntryEditActivity));
|
||||||
|
|
||||||
PwGroup parent = pw;
|
PwGroup parent = pw;
|
||||||
i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString());
|
i.PutExtra(KeyParent, parent.Uuid.ToHexString());
|
||||||
|
|
||||||
appTask.ToIntent(i);
|
appTask.ToIntent(i);
|
||||||
|
|
||||||
act.StartActivityForResult(i, 0);
|
act.StartActivityForResult(i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScrollView scroll;
|
bool _closeForReload;
|
||||||
|
|
||||||
bool mCloseForReload;
|
AppTask _appTask;
|
||||||
|
|
||||||
AppTask mAppTask;
|
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
if (this.LastNonConfigurationInstance != null)
|
if (LastNonConfigurationInstance != null)
|
||||||
{
|
{
|
||||||
//bug in Mono for Android or whatever: after config change the extra fields are wrong
|
//bug in Mono for Android or whatever: after config change the extra fields are wrong
|
||||||
// -> reload:
|
// -> reload:
|
||||||
reload();
|
Reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
_appTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||||
|
|
||||||
SetContentView(Resource.Layout.entry_edit);
|
SetContentView(Resource.Layout.entry_edit);
|
||||||
mCloseForReload = false;
|
_closeForReload = false;
|
||||||
|
|
||||||
// Likely the app has been killed exit the activity
|
// Likely the app has been killed exit the activity
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
if (! db.Open)
|
if (! db.Open)
|
||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
@ -106,34 +99,34 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Intent.GetBooleanExtra(Intent_ContinueWithEditing, false))
|
if (Intent.GetBooleanExtra(IntentContinueWithEditing, false))
|
||||||
{
|
{
|
||||||
//property "State" will return the state
|
//property "State" will return the state
|
||||||
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
App.entryEditActivityState = new EntryEditActivityState();
|
App.Kp2a.EntryEditActivityState = new EntryEditActivityState();
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
State.mShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
State.ShowPassword = ! prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||||
|
|
||||||
Intent i = Intent;
|
Intent i = Intent;
|
||||||
String uuidBytes = i.GetStringExtra(KEY_ENTRY);
|
String uuidBytes = i.GetStringExtra(KeyEntry);
|
||||||
|
|
||||||
PwUuid entryId = PwUuid.Zero;
|
PwUuid entryId = PwUuid.Zero;
|
||||||
if (uuidBytes != null)
|
if (uuidBytes != null)
|
||||||
entryId = new KeePassLib.PwUuid(MemUtil.HexStringToByteArray(uuidBytes));
|
entryId = new PwUuid(MemUtil.HexStringToByteArray(uuidBytes));
|
||||||
|
|
||||||
State.parentGroup = null;
|
State.ParentGroup = null;
|
||||||
if (entryId.EqualsValue(PwUuid.Zero))
|
if (entryId.EqualsValue(PwUuid.Zero))
|
||||||
{
|
{
|
||||||
String groupId = i.GetStringExtra(KEY_PARENT);
|
String groupId = i.GetStringExtra(KeyParent);
|
||||||
|
|
||||||
State.parentGroup = db.groups [new PwUuid(MemUtil.HexStringToByteArray(groupId))];
|
State.ParentGroup = db.Groups [new PwUuid(MemUtil.HexStringToByteArray(groupId))];
|
||||||
|
|
||||||
State.mEntryInDatabase = new PwEntry(true, true);
|
State.EntryInDatabase = new PwEntry(true, true);
|
||||||
State.mEntryInDatabase.Strings.Set(PwDefs.UserNameField, new ProtectedString(
|
State.EntryInDatabase.Strings.Set(PwDefs.UserNameField, new ProtectedString(
|
||||||
db.pm.MemoryProtection.ProtectUserName, db.pm.DefaultUserName));
|
db.KpDatabase.MemoryProtection.ProtectUserName, db.KpDatabase.DefaultUserName));
|
||||||
|
|
||||||
/*KPDesktop
|
/*KPDesktop
|
||||||
* ProtectedString psAutoGen;
|
* ProtectedString psAutoGen;
|
||||||
@ -149,12 +142,12 @@ namespace keepass2android
|
|||||||
pwe.ExpiryTime = DateTime.Now.AddDays(nExpireDays);
|
pwe.ExpiryTime = DateTime.Now.AddDays(nExpireDays);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if ((State.parentGroup.IconId != PwIcon.Folder) && (State.parentGroup.IconId != PwIcon.FolderOpen) &&
|
if ((State.ParentGroup.IconId != PwIcon.Folder) && (State.ParentGroup.IconId != PwIcon.FolderOpen) &&
|
||||||
(State.parentGroup.IconId != PwIcon.FolderPackage))
|
(State.ParentGroup.IconId != PwIcon.FolderPackage))
|
||||||
{
|
{
|
||||||
State.mEntryInDatabase.IconId = State.parentGroup.IconId; // Inherit icon from group
|
State.EntryInDatabase.IconId = State.ParentGroup.IconId; // Inherit icon from group
|
||||||
}
|
}
|
||||||
State.mEntryInDatabase.CustomIconUuid = State.parentGroup.CustomIconUuid;
|
State.EntryInDatabase.CustomIconUuid = State.ParentGroup.CustomIconUuid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KPDesktop
|
* KPDesktop
|
||||||
@ -174,52 +167,52 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
mAppTask.PrepareNewEntry(State.mEntryInDatabase);
|
_appTask.PrepareNewEntry(State.EntryInDatabase);
|
||||||
State.mIsNew = true;
|
State.IsNew = true;
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
||||||
System.Diagnostics.Debug.Assert(entryId != null);
|
System.Diagnostics.Debug.Assert(entryId != null);
|
||||||
|
|
||||||
State.mEntryInDatabase = db.entries [entryId];
|
State.EntryInDatabase = db.Entries [entryId];
|
||||||
State.mIsNew = false;
|
State.IsNew = false;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
State.mEntry = State.mEntryInDatabase.CloneDeep();
|
State.Entry = State.EntryInDatabase.CloneDeep();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!State.mEntryModified)
|
if (!State.EntryModified)
|
||||||
SetResult(KeePass.EXIT_NORMAL);
|
SetResult(KeePass.ExitNormal);
|
||||||
else
|
else
|
||||||
SetResult(KeePass.EXIT_REFRESH_TITLE);
|
SetResult(KeePass.ExitRefreshTitle);
|
||||||
|
|
||||||
|
|
||||||
fillData();
|
FillData();
|
||||||
View scrollView = FindViewById(Resource.Id.entry_scroll);
|
View scrollView = FindViewById(Resource.Id.entry_scroll);
|
||||||
scrollView.ScrollBarStyle = ScrollbarStyles.InsideInset;
|
scrollView.ScrollBarStyle = ScrollbarStyles.InsideInset;
|
||||||
|
|
||||||
ImageButton iconButton = (ImageButton)FindViewById(Resource.Id.icon_button);
|
ImageButton iconButton = (ImageButton)FindViewById(Resource.Id.icon_button);
|
||||||
|
|
||||||
if (State.mSelectedIcon)
|
if (State.SelectedIcon)
|
||||||
{
|
{
|
||||||
//TODO: custom image
|
//TODO: custom image
|
||||||
iconButton.SetImageResource(Icons.iconToResId(State.mSelectedIconID));
|
iconButton.SetImageResource(Icons.IconToResId(State.SelectedIconId));
|
||||||
}
|
}
|
||||||
iconButton.Click += (sender, evt) => {
|
iconButton.Click += (sender, evt) => {
|
||||||
UpdateEntryFromUi(State.mEntry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
IconPickerActivity.Launch(this);
|
IconPickerActivity.Launch(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Generate password button
|
// Generate password button
|
||||||
Button generatePassword = (Button)FindViewById(Resource.Id.generate_button);
|
Button generatePassword = (Button)FindViewById(Resource.Id.generate_button);
|
||||||
generatePassword.Click += (object sender, EventArgs e) => {
|
generatePassword.Click += (sender, e) => {
|
||||||
UpdateEntryFromUi(State.mEntry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
GeneratePasswordActivity.Launch(this);
|
GeneratePasswordActivity.Launch(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -241,14 +234,14 @@ namespace keepass2android
|
|||||||
save = FindViewById(Resource.Id.entry_save);
|
save = FindViewById(Resource.Id.entry_save);
|
||||||
|
|
||||||
}
|
}
|
||||||
save.Click += (object sender, EventArgs e) =>
|
save.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
SaveEntry();
|
SaveEntry();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Respect mask password setting
|
// Respect mask password setting
|
||||||
if (State.mShowPassword) {
|
if (State.ShowPassword) {
|
||||||
EditText pass = (EditText) FindViewById(Resource.Id.entry_password);
|
EditText pass = (EditText) FindViewById(Resource.Id.entry_password);
|
||||||
EditText conf = (EditText) FindViewById(Resource.Id.entry_confpassword);
|
EditText conf = (EditText) FindViewById(Resource.Id.entry_confpassword);
|
||||||
|
|
||||||
@ -256,11 +249,9 @@ namespace keepass2android
|
|||||||
conf.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
conf.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
scroll = (ScrollView) FindViewById(Resource.Id.entry_scroll);
|
|
||||||
|
|
||||||
Button addButton = (Button) FindViewById(Resource.Id.add_advanced);
|
Button addButton = (Button) FindViewById(Resource.Id.add_advanced);
|
||||||
addButton.Visibility = ViewStates.Visible;
|
addButton.Visibility = ViewStates.Visible;
|
||||||
addButton.Click += (object sender, EventArgs e) =>
|
addButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||||
|
|
||||||
@ -268,7 +259,7 @@ namespace keepass2android
|
|||||||
LinearLayout ees = CreateExtraStringView(pair);
|
LinearLayout ees = CreateExtraStringView(pair);
|
||||||
container.AddView(ees);
|
container.AddView(ees);
|
||||||
|
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
|
|
||||||
TextView keyView = (TextView) ees.FindViewById(Resource.Id.title);
|
TextView keyView = (TextView) ees.FindViewById(Resource.Id.title);
|
||||||
keyView.RequestFocus();
|
keyView.RequestFocus();
|
||||||
@ -276,16 +267,16 @@ namespace keepass2android
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
|
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).CheckedChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
State.mEntry.Expires = e.IsChecked;
|
State.Entry.Expires = e.IsChecked;
|
||||||
if (e.IsChecked)
|
if (e.IsChecked)
|
||||||
{
|
{
|
||||||
if (State.mEntry.ExpiryTime < DateTime.Now)
|
if (State.Entry.ExpiryTime < DateTime.Now)
|
||||||
State.mEntry.ExpiryTime = DateTime.Now;
|
State.Entry.ExpiryTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
updateExpires();
|
UpdateExpires();
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -293,33 +284,33 @@ namespace keepass2android
|
|||||||
|
|
||||||
void SaveEntry()
|
void SaveEntry()
|
||||||
{
|
{
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
EntryEditActivity act = this;
|
EntryEditActivity act = this;
|
||||||
|
|
||||||
if (!validateBeforeSaving())
|
if (!ValidateBeforeSaving())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PwEntry initialEntry = State.mEntryInDatabase.CloneDeep();
|
PwEntry initialEntry = State.EntryInDatabase.CloneDeep();
|
||||||
|
|
||||||
PwEntry newEntry = State.mEntryInDatabase;
|
PwEntry newEntry = State.EntryInDatabase;
|
||||||
|
|
||||||
//Clone history and re-assign:
|
//Clone history and re-assign:
|
||||||
newEntry.History = newEntry.History.CloneDeep();
|
newEntry.History = newEntry.History.CloneDeep();
|
||||||
|
|
||||||
//Based on KeePass Desktop
|
//Based on KeePass Desktop
|
||||||
bool bCreateBackup = (!State.mIsNew);
|
bool bCreateBackup = (!State.IsNew);
|
||||||
if(bCreateBackup) newEntry.CreateBackup(null);
|
if(bCreateBackup) newEntry.CreateBackup(null);
|
||||||
|
|
||||||
if (State.mSelectedIcon == false) {
|
if (State.SelectedIcon == false) {
|
||||||
if (State.mIsNew) {
|
if (State.IsNew) {
|
||||||
newEntry.IconId = PwIcon.Key;
|
newEntry.IconId = PwIcon.Key;
|
||||||
} else {
|
} else {
|
||||||
// Keep previous icon, if no new one was selected
|
// Keep previous icon, if no new one was selected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newEntry.IconId = State.mSelectedIconID;
|
newEntry.IconId = State.SelectedIconId;
|
||||||
newEntry.CustomIconUuid = State.mSelectedCustomIconID;
|
newEntry.CustomIconUuid = State.SelectedCustomIconId;
|
||||||
}
|
}
|
||||||
/* KPDesktop
|
/* KPDesktop
|
||||||
if(m_cbCustomForegroundColor.Checked)
|
if(m_cbCustomForegroundColor.Checked)
|
||||||
@ -332,11 +323,11 @@ namespace keepass2android
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
UpdateEntryFromUi(newEntry);
|
UpdateEntryFromUi(newEntry);
|
||||||
newEntry.Binaries = State.mEntry.Binaries;
|
newEntry.Binaries = State.Entry.Binaries;
|
||||||
newEntry.Expires = State.mEntry.Expires;
|
newEntry.Expires = State.Entry.Expires;
|
||||||
if (newEntry.Expires)
|
if (newEntry.Expires)
|
||||||
{
|
{
|
||||||
newEntry.ExpiryTime = State.mEntry.ExpiryTime;
|
newEntry.ExpiryTime = State.Entry.ExpiryTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -358,19 +349,19 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
// If only history items have been modified (deleted) => undo
|
// If only history items have been modified (deleted) => undo
|
||||||
// backup, but without restoring the last mod time
|
// backup, but without restoring the last mod time
|
||||||
PwCompareOptions cmpOptNH = (cmpOpt | PwCompareOptions.IgnoreHistory);
|
PwCompareOptions cmpOptNh = (cmpOpt | PwCompareOptions.IgnoreHistory);
|
||||||
if(newEntry.EqualsEntry(initialEntry, cmpOptNH, MemProtCmpMode.CustomOnly))
|
if(newEntry.EqualsEntry(initialEntry, cmpOptNh, MemProtCmpMode.CustomOnly))
|
||||||
bUndoBackup = true;
|
bUndoBackup = true;
|
||||||
}
|
}
|
||||||
if(bUndoBackup) newEntry.History.RemoveAt(newEntry.History.UCount - 1);
|
if(bUndoBackup) newEntry.History.RemoveAt(newEntry.History.UCount - 1);
|
||||||
|
|
||||||
newEntry.MaintainBackups(db.pm);
|
newEntry.MaintainBackups(db.KpDatabase);
|
||||||
|
|
||||||
//if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(State.mEntry.Strings.ReadSafe (PwDefs.TitleField)) ) {
|
//if ( newEntry.Strings.ReadSafe (PwDefs.TitleField).Equals(State.Entry.Strings.ReadSafe (PwDefs.TitleField)) ) {
|
||||||
// SetResult(KeePass.EXIT_REFRESH);
|
// SetResult(KeePass.EXIT_REFRESH);
|
||||||
//} else {
|
//} else {
|
||||||
//it's safer to always update the title as we might add further information in the title like expiry etc.
|
//it's safer to always update the title as we might add further information in the title like expiry etc.
|
||||||
SetResult(KeePass.EXIT_REFRESH_TITLE);
|
SetResult(KeePass.ExitRefreshTitle);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
RunnableOnFinish runnable;
|
RunnableOnFinish runnable;
|
||||||
@ -381,57 +372,57 @@ namespace keepass2android
|
|||||||
Finish();
|
Finish();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
OnFinish.displayMessage(this, message);
|
OnFinish.DisplayMessage(this, message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) =>
|
ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) =>
|
||||||
{
|
{
|
||||||
if (success)
|
if (success)
|
||||||
mAppTask.AfterAddNewEntry(this, newEntry);
|
_appTask.AfterAddNewEntry(this, newEntry);
|
||||||
},closeOrShowError);
|
},closeOrShowError);
|
||||||
|
|
||||||
if ( State.mIsNew ) {
|
if ( State.IsNew ) {
|
||||||
runnable = AddEntry.getInstance(this, App.getDB(), newEntry, State.parentGroup, afterAddEntry);
|
runnable = AddEntry.GetInstance(this, App.Kp2a.GetDb(), newEntry, State.ParentGroup, afterAddEntry);
|
||||||
} else {
|
} else {
|
||||||
runnable = new UpdateEntry(this, App.getDB(), initialEntry, newEntry, closeOrShowError);
|
runnable = new UpdateEntry(this, App.Kp2a.GetDb(), initialEntry, newEntry, closeOrShowError);
|
||||||
}
|
}
|
||||||
ProgressTask pt = new ProgressTask(act, runnable, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateEntryFromUi(PwEntry entry)
|
void UpdateEntryFromUi(PwEntry entry)
|
||||||
{
|
{
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
EntryEditActivity act = this;
|
EntryEditActivity act = this;
|
||||||
|
|
||||||
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.pm.MemoryProtection.ProtectTitle,
|
entry.Strings.Set(PwDefs.TitleField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectTitle,
|
||||||
Util.getEditText(act, Resource.Id.entry_title)));
|
Util.getEditText(act, Resource.Id.entry_title)));
|
||||||
entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.pm.MemoryProtection.ProtectUserName,
|
entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUserName,
|
||||||
Util.getEditText(act, Resource.Id.entry_user_name)));
|
Util.getEditText(act, Resource.Id.entry_user_name)));
|
||||||
|
|
||||||
String pass = Util.getEditText(act, Resource.Id.entry_password);
|
String pass = Util.getEditText(act, Resource.Id.entry_password);
|
||||||
byte[] password = StrUtil.Utf8.GetBytes(pass);
|
byte[] password = StrUtil.Utf8.GetBytes(pass);
|
||||||
entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.pm.MemoryProtection.ProtectPassword,
|
entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectPassword,
|
||||||
password));
|
password));
|
||||||
MemUtil.ZeroByteArray(password);
|
MemUtil.ZeroByteArray(password);
|
||||||
|
|
||||||
entry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.pm.MemoryProtection.ProtectUrl,
|
entry.Strings.Set(PwDefs.UrlField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectUrl,
|
||||||
Util.getEditText(act, Resource.Id.entry_url)));
|
Util.getEditText(act, Resource.Id.entry_url)));
|
||||||
entry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.pm.MemoryProtection.ProtectNotes,
|
entry.Strings.Set(PwDefs.NotesField, new ProtectedString(db.KpDatabase.MemoryProtection.ProtectNotes,
|
||||||
Util.getEditText(act, Resource.Id.entry_comment)));
|
Util.getEditText(act, Resource.Id.entry_comment)));
|
||||||
|
|
||||||
// Validate expiry date
|
// Validate expiry date
|
||||||
DateTime newExpiry = new DateTime();
|
DateTime newExpiry = new DateTime();
|
||||||
if ((State.mEntry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry)))
|
if ((State.Entry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry)))
|
||||||
{
|
{
|
||||||
//ignore here
|
//ignore here
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
State.mEntry.ExpiryTime = newExpiry;
|
State.Entry.ExpiryTime = newExpiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all non standard strings
|
// Delete all non standard strings
|
||||||
@ -456,7 +447,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
bool protect = true;
|
bool protect = true;
|
||||||
ProtectedString initialString = State.mEntryInDatabase.Strings.Get(key);
|
ProtectedString initialString = State.EntryInDatabase.Strings.Get(key);
|
||||||
if (initialString != null)
|
if (initialString != null)
|
||||||
protect = initialString.IsProtected;
|
protect = initialString.IsProtected;
|
||||||
entry.Strings.Set(key, new ProtectedString(protect, value));
|
entry.Strings.Set(key, new ProtectedString(protect, value));
|
||||||
@ -484,39 +475,39 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addBinaryOrAsk(string filename)
|
void AddBinaryOrAsk(string filename)
|
||||||
{
|
{
|
||||||
string strItem = UrlUtil.GetFileName(filename);
|
string strItem = UrlUtil.GetFileName(filename);
|
||||||
|
|
||||||
if(State.mEntry.Binaries.Get(strItem) != null)
|
if(State.Entry.Binaries.Get(strItem) != null)
|
||||||
{
|
{
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title));
|
builder.SetTitle(GetString(Resource.String.AskOverwriteBinary_title));
|
||||||
|
|
||||||
builder.SetMessage(GetString(Resource.String.AskOverwriteBinary));
|
builder.SetMessage(GetString(Resource.String.AskOverwriteBinary));
|
||||||
|
|
||||||
builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetPositiveButton(GetString(Resource.String.AskOverwriteBinary_yes), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
addBinary(filename, true);
|
AddBinary(filename, true);
|
||||||
}));
|
});
|
||||||
|
|
||||||
builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetNegativeButton(GetString(Resource.String.AskOverwriteBinary_no), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
addBinary(filename, false);
|
AddBinary(filename, false);
|
||||||
}));
|
});
|
||||||
|
|
||||||
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
||||||
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}));
|
(dlgSender, dlgEvt) => {});
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
addBinary(filename, true);
|
AddBinary(filename, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addBinary(string filename, bool overwrite)
|
void AddBinary(string filename, bool overwrite)
|
||||||
{
|
{
|
||||||
string strItem = UrlUtil.GetFileName(filename);
|
string strItem = UrlUtil.GetFileName(filename);
|
||||||
|
|
||||||
@ -528,8 +519,8 @@ namespace keepass2android
|
|||||||
int nTry = 0;
|
int nTry = 0;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
string strNewName = strFileName + nTry.ToString() + strExtension;
|
string strNewName = strFileName + nTry.ToString(CultureInfo.InvariantCulture) + strExtension;
|
||||||
if(State.mEntry.Binaries.Get(strNewName) == null)
|
if(State.Entry.Binaries.Get(strNewName) == null)
|
||||||
{
|
{
|
||||||
strItem = strNewName;
|
strItem = strNewName;
|
||||||
break;
|
break;
|
||||||
@ -541,29 +532,26 @@ namespace keepass2android
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] vBytes = File.ReadAllBytes(filename);
|
byte[] vBytes = File.ReadAllBytes(filename);
|
||||||
if(vBytes != null)
|
|
||||||
{
|
|
||||||
ProtectedBinary pb = new ProtectedBinary(false, vBytes);
|
ProtectedBinary pb = new ProtectedBinary(false, vBytes);
|
||||||
State.mEntry.Binaries.Set(strItem, pb);
|
State.Entry.Binaries.Set(strItem, pb);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch(Exception exAttach)
|
catch(Exception exAttach)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, ToastLength.Long).Show();
|
Toast.MakeText(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, ToastLength.Long).Show();
|
||||||
}
|
}
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
populateBinaries();
|
PopulateBinaries();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
mAppTask.ToBundle(outState);
|
_appTask.ToBundle(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnBackPressed()
|
public override void OnBackPressed()
|
||||||
{
|
{
|
||||||
if (State.mEntryModified == false)
|
if (State.EntryModified == false)
|
||||||
{
|
{
|
||||||
base.OnBackPressed();
|
base.OnBackPressed();
|
||||||
} else
|
} else
|
||||||
@ -573,16 +561,16 @@ namespace keepass2android
|
|||||||
|
|
||||||
builder.SetMessage(GetString(Resource.String.AskDiscardChanges));
|
builder.SetMessage(GetString(Resource.String.AskDiscardChanges));
|
||||||
|
|
||||||
builder.SetPositiveButton(GetString(Android.Resource.String.Yes), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetPositiveButton(GetString(Android.Resource.String.Yes), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
|
|
||||||
}));
|
});
|
||||||
|
|
||||||
builder.SetNegativeButton(GetString(Android.Resource.String.No), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetNegativeButton(GetString(Android.Resource.String.No), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
@ -591,15 +579,15 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload() {
|
public void Reload() {
|
||||||
//this reload ìs necessary to overcome a strange problem with the extra string fields which get lost
|
//this reload ìs necessary to overcome a strange problem with the extra string fields which get lost
|
||||||
//somehow after re-creating the activity. Maybe a Mono for Android bug?
|
//somehow after re-creating the activity. Maybe a Mono for Android bug?
|
||||||
Intent intent = Intent;
|
Intent intent = Intent;
|
||||||
intent.PutExtra(Intent_ContinueWithEditing, true);
|
intent.PutExtra(IntentContinueWithEditing, true);
|
||||||
OverridePendingTransition(0, 0);
|
OverridePendingTransition(0, 0);
|
||||||
intent.AddFlags(ActivityFlags.NoAnimation);
|
intent.AddFlags(ActivityFlags.NoAnimation);
|
||||||
mCloseForReload = true;
|
_closeForReload = true;
|
||||||
SetResult(KeePass.EXIT_REFRESH_TITLE); //probably the entry will be modified -> let the EditActivity refresh to be safe
|
SetResult(KeePass.ExitRefreshTitle); //probably the entry will be modified -> let the EditActivity refresh to be safe
|
||||||
Finish();
|
Finish();
|
||||||
|
|
||||||
OverridePendingTransition(0, 0);
|
OverridePendingTransition(0, 0);
|
||||||
@ -610,30 +598,30 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
switch ((int)resultCode)
|
switch ((int)resultCode)
|
||||||
{
|
{
|
||||||
case RESULT_OK_ICON_PICKER:
|
case ResultOkIconPicker:
|
||||||
State.mSelectedIconID = (PwIcon) data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID);
|
State.SelectedIconId = (PwIcon) data.Extras.GetInt(IconPickerActivity.KeyIconId);
|
||||||
State.mSelectedCustomIconID = PwUuid.Zero;
|
State.SelectedCustomIconId = PwUuid.Zero;
|
||||||
String customIconIdString = data.Extras.GetString(IconPickerActivity.KEY_CUSTOM_ICON_ID);
|
String customIconIdString = data.Extras.GetString(IconPickerActivity.KeyCustomIconId);
|
||||||
if (!String.IsNullOrEmpty(customIconIdString))
|
if (!String.IsNullOrEmpty(customIconIdString))
|
||||||
State.mSelectedCustomIconID = new PwUuid(MemUtil.HexStringToByteArray(customIconIdString));
|
State.SelectedCustomIconId = new PwUuid(MemUtil.HexStringToByteArray(customIconIdString));
|
||||||
State.mSelectedIcon = true;
|
State.SelectedIcon = true;
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
reload();
|
Reload();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RESULT_OK_PASSWORD_GENERATOR:
|
case ResultOkPasswordGenerator:
|
||||||
String generatedPassword = data.GetStringExtra("keepass2android.password.generated_password");
|
String generatedPassword = data.GetStringExtra("keepass2android.password.generated_password");
|
||||||
|
|
||||||
byte[] password = StrUtil.Utf8.GetBytes(generatedPassword);
|
byte[] password = StrUtil.Utf8.GetBytes(generatedPassword);
|
||||||
State.mEntry.Strings.Set(PwDefs.PasswordField, new ProtectedString(App.getDB().pm.MemoryProtection.ProtectPassword,
|
State.Entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(App.Kp2a.GetDb().KpDatabase.MemoryProtection.ProtectPassword,
|
||||||
password));
|
password));
|
||||||
MemUtil.ZeroByteArray(password);
|
MemUtil.ZeroByteArray(password);
|
||||||
|
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
reload();
|
Reload();
|
||||||
break;
|
break;
|
||||||
case (int)Result.Ok:
|
case (int)Result.Ok:
|
||||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_BINARY)
|
if (requestCode == Intents.RequestCodeFileBrowseForBinary)
|
||||||
{
|
{
|
||||||
string filename = Util.IntentToFilename(data);
|
string filename = Util.IntentToFilename(data);
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
@ -642,39 +630,35 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
filename = Java.Net.URLDecoder.Decode(filename);
|
filename = Java.Net.URLDecoder.Decode(filename);
|
||||||
addBinaryOrAsk(filename);
|
AddBinaryOrAsk(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reload();
|
Reload();
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case (int)Result.Canceled:
|
case (int)Result.Canceled:
|
||||||
reload();
|
Reload();
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateBinaries()
|
void PopulateBinaries()
|
||||||
{
|
{
|
||||||
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
||||||
binariesGroup.RemoveAllViews();
|
binariesGroup.RemoveAllViews();
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FillParent, RelativeLayout.LayoutParams.WrapContent);
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
|
||||||
foreach (KeyValuePair<string, ProtectedBinary> pair in State.mEntry.Binaries)
|
foreach (KeyValuePair<string, ProtectedBinary> pair in State.Entry.Binaries)
|
||||||
{
|
{
|
||||||
String key = pair.Key;
|
String key = pair.Key;
|
||||||
Button binaryButton = new Button(this);
|
Button binaryButton = new Button(this) {Text = key};
|
||||||
|
|
||||||
binaryButton.Text = key;
|
|
||||||
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null);
|
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null);
|
||||||
binaryButton.Click += (object sender, EventArgs e) =>
|
binaryButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
Button btnSender = (Button)(sender);
|
State.Entry.Binaries.Remove(key);
|
||||||
State.mEntry.Binaries.Remove(key);
|
PopulateBinaries();
|
||||||
populateBinaries();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
binariesGroup.AddView(binaryButton,layoutParams);
|
binariesGroup.AddView(binaryButton,layoutParams);
|
||||||
@ -682,19 +666,18 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button addBinaryButton = new Button(this);
|
Button addBinaryButton = new Button(this) {Text = GetString(Resource.String.add_binary)};
|
||||||
addBinaryButton.Text = GetString(Resource.String.add_binary);
|
|
||||||
addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
|
addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
|
||||||
addBinaryButton.Click += (object sender, EventArgs e) =>
|
addBinaryButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
Util.showBrowseDialog("/mnt/sdcard", this, Intents.REQUEST_CODE_FILE_BROWSE_FOR_BINARY, false);
|
Util.showBrowseDialog("/mnt/sdcard", this, Intents.RequestCodeFileBrowseForBinary, false);
|
||||||
|
|
||||||
};
|
};
|
||||||
binariesGroup.AddView(addBinaryButton,layoutParams);
|
binariesGroup.AddView(addBinaryButton,layoutParams);
|
||||||
|
|
||||||
var binariesLabel = FindViewById(Resource.Id.entry_binaries_label);
|
var binariesLabel = FindViewById(Resource.Id.entry_binaries_label);
|
||||||
if (binariesLabel != null)
|
if (binariesLabel != null)
|
||||||
binariesLabel.Visibility = State.mEntry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
binariesLabel.Visibility = State.Entry.Binaries.UCount > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||||
}
|
}
|
||||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||||
base.OnCreateOptionsMenu(menu);
|
base.OnCreateOptionsMenu(menu);
|
||||||
@ -704,7 +687,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
IMenuItem togglePassword = menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||||
if ( State.mShowPassword ) {
|
if ( State.ShowPassword ) {
|
||||||
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
togglePassword.SetTitle(Resource.String.menu_hide_password);
|
||||||
} else {
|
} else {
|
||||||
togglePassword.SetTitle(Resource.String.show_password);
|
togglePassword.SetTitle(Resource.String.show_password);
|
||||||
@ -725,14 +708,14 @@ namespace keepass2android
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_toggle_pass:
|
case Resource.Id.menu_toggle_pass:
|
||||||
if ( State.mShowPassword ) {
|
if ( State.ShowPassword ) {
|
||||||
item.SetTitle(Resource.String.show_password);
|
item.SetTitle(Resource.String.show_password);
|
||||||
State.mShowPassword = false;
|
State.ShowPassword = false;
|
||||||
} else {
|
} else {
|
||||||
item.SetTitle(Resource.String.menu_hide_password);
|
item.SetTitle(Resource.String.menu_hide_password);
|
||||||
State.mShowPassword = true;
|
State.ShowPassword = true;
|
||||||
}
|
}
|
||||||
setPasswordStyle();
|
SetPasswordStyle();
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_cancel_edit:
|
case Resource.Id.menu_cancel_edit:
|
||||||
Finish();
|
Finish();
|
||||||
@ -766,11 +749,11 @@ namespace keepass2android
|
|||||||
return base.OnOptionsItemSelected(item);
|
return base.OnOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPasswordStyle() {
|
private void SetPasswordStyle() {
|
||||||
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
||||||
TextView confpassword = (TextView) FindViewById(Resource.Id.entry_confpassword);
|
TextView confpassword = (TextView) FindViewById(Resource.Id.entry_confpassword);
|
||||||
|
|
||||||
if ( State.mShowPassword ) {
|
if ( State.ShowPassword ) {
|
||||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||||
confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
confpassword.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||||
|
|
||||||
@ -780,23 +763,23 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateExpires()
|
void UpdateExpires()
|
||||||
{
|
{
|
||||||
if (State.mEntry.Expires)
|
if (State.Entry.Expires)
|
||||||
{
|
{
|
||||||
populateText(Resource.Id.entry_expires, getDateTime(State.mEntry.ExpiryTime));
|
PopulateText(Resource.Id.entry_expires, getDateTime(State.Entry.ExpiryTime));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
populateText(Resource.Id.entry_expires, GetString(Resource.String.never));
|
PopulateText(Resource.Id.entry_expires, GetString(Resource.String.never));
|
||||||
}
|
}
|
||||||
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).Checked = State.mEntry.Expires;
|
((CheckBox)FindViewById(Resource.Id.entry_expires_checkbox)).Checked = State.Entry.Expires;
|
||||||
((EditText)FindViewById(Resource.Id.entry_expires)).Enabled = State.mEntry.Expires;
|
FindViewById(Resource.Id.entry_expires).Enabled = State.Entry.Expires;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Java.Lang.Object OnRetainNonConfigurationInstance()
|
public override Java.Lang.Object OnRetainNonConfigurationInstance()
|
||||||
{
|
{
|
||||||
UpdateEntryFromUi(State.mEntry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,31 +787,31 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
LinearLayout ees = (LinearLayout)LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
LinearLayout ees = (LinearLayout)LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
||||||
((TextView)ees.FindViewById(Resource.Id.title)).Text = pair.Key;
|
((TextView)ees.FindViewById(Resource.Id.title)).Text = pair.Key;
|
||||||
((TextView)ees.FindViewById(Resource.Id.title)).TextChanged += (sender, e) => State.mEntryModified = true;
|
((TextView)ees.FindViewById(Resource.Id.title)).TextChanged += (sender, e) => State.EntryModified = true;
|
||||||
((TextView)ees.FindViewById(Resource.Id.value)).Text = pair.Value.ReadString();
|
((TextView)ees.FindViewById(Resource.Id.value)).Text = pair.Value.ReadString();
|
||||||
((TextView)ees.FindViewById(Resource.Id.value)).TextChanged += (sender, e) => State.mEntryModified = true;
|
((TextView)ees.FindViewById(Resource.Id.value)).TextChanged += (sender, e) => State.EntryModified = true;
|
||||||
ees.FindViewById(Resource.Id.delete).Click += (sender, e) => deleteAdvancedString((View)sender);
|
ees.FindViewById(Resource.Id.delete).Click += (sender, e) => DeleteAdvancedString((View)sender);
|
||||||
return ees;
|
return ees;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillData() {
|
private void FillData() {
|
||||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||||
App.getDB().drawFactory.assignDrawableTo(currIconButton, Resources, App.getDB().pm, State.mEntry.IconId, State.mEntry.CustomIconUuid);
|
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(currIconButton, Resources, App.Kp2a.GetDb().KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid);
|
||||||
|
|
||||||
populateText(Resource.Id.entry_title, State.mEntry.Strings.ReadSafe (PwDefs.TitleField));
|
PopulateText(Resource.Id.entry_title, State.Entry.Strings.ReadSafe (PwDefs.TitleField));
|
||||||
populateText(Resource.Id.entry_user_name, State.mEntry.Strings.ReadSafe (PwDefs.UserNameField));
|
PopulateText(Resource.Id.entry_user_name, State.Entry.Strings.ReadSafe (PwDefs.UserNameField));
|
||||||
populateText(Resource.Id.entry_url, State.mEntry.Strings.ReadSafe (PwDefs.UrlField));
|
PopulateText(Resource.Id.entry_url, State.Entry.Strings.ReadSafe (PwDefs.UrlField));
|
||||||
|
|
||||||
String password = State.mEntry.Strings.ReadSafe(PwDefs.PasswordField);
|
String password = State.Entry.Strings.ReadSafe(PwDefs.PasswordField);
|
||||||
populateText(Resource.Id.entry_password, password);
|
PopulateText(Resource.Id.entry_password, password);
|
||||||
populateText(Resource.Id.entry_confpassword, password);
|
PopulateText(Resource.Id.entry_confpassword, password);
|
||||||
setPasswordStyle();
|
SetPasswordStyle();
|
||||||
|
|
||||||
populateText(Resource.Id.entry_comment, State.mEntry.Strings.ReadSafe (PwDefs.NotesField));
|
PopulateText(Resource.Id.entry_comment, State.Entry.Strings.ReadSafe (PwDefs.NotesField));
|
||||||
|
|
||||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||||
|
|
||||||
foreach (var pair in State.mEntry.Strings)
|
foreach (var pair in State.Entry.Strings)
|
||||||
{
|
{
|
||||||
String key = pair.Key;
|
String key = pair.Key;
|
||||||
|
|
||||||
@ -838,22 +821,22 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
populateBinaries();
|
PopulateBinaries();
|
||||||
|
|
||||||
populateText(Resource.Id.entry_override_url, State.mEntry.OverrideUrl);
|
PopulateText(Resource.Id.entry_override_url, State.Entry.OverrideUrl);
|
||||||
populateText(Resource.Id.entry_tags, StrUtil.TagsToString(State.mEntry.Tags, true));
|
PopulateText(Resource.Id.entry_tags, StrUtil.TagsToString(State.Entry.Tags, true));
|
||||||
|
|
||||||
updateExpires();
|
UpdateExpires();
|
||||||
}
|
}
|
||||||
private String getDateTime(System.DateTime dt) {
|
private String getDateTime(DateTime dt) {
|
||||||
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
return dt.ToString ("g", CultureInfo.CurrentUICulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void deleteAdvancedString(View view) {
|
public void DeleteAdvancedString(View view) {
|
||||||
var section = view.Parent;
|
var section = view.Parent;
|
||||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||||
State.mEntryModified = true;
|
State.EntryModified = true;
|
||||||
for (int i = 0; i < container.ChildCount; i++) {
|
for (int i = 0; i < container.ChildCount; i++) {
|
||||||
var ees = container.GetChildAt(i);
|
var ees = container.GetChildAt(i);
|
||||||
if (ees == section) {
|
if (ees == section) {
|
||||||
@ -865,7 +848,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected bool validateBeforeSaving() {
|
protected bool ValidateBeforeSaving() {
|
||||||
// Require title
|
// Require title
|
||||||
String title = Util.getEditText(this, Resource.Id.entry_title);
|
String title = Util.getEditText(this, Resource.Id.entry_title);
|
||||||
if ( title.Length == 0 ) {
|
if ( title.Length == 0 ) {
|
||||||
@ -883,17 +866,14 @@ namespace keepass2android
|
|||||||
|
|
||||||
// Validate expiry date
|
// Validate expiry date
|
||||||
DateTime newExpiry = new DateTime();
|
DateTime newExpiry = new DateTime();
|
||||||
if ((State.mEntry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry)))
|
if ((State.Entry.Expires) && (!DateTime.TryParse( Util.getEditText(this,Resource.Id.entry_expires), out newExpiry)))
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show();
|
Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
State.Entry.ExpiryTime = newExpiry;
|
||||||
{
|
|
||||||
State.mEntry.ExpiryTime = newExpiry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||||
for (int i = 0; i < container.ChildCount; i++) {
|
for (int i = 0; i < container.ChildCount; i++) {
|
||||||
View ees = container.GetChildAt(i);
|
View ees = container.GetChildAt(i);
|
||||||
@ -912,16 +892,16 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void populateText(int viewId, String text) {
|
private void PopulateText(int viewId, String text) {
|
||||||
TextView tv = (TextView) FindViewById(viewId);
|
TextView tv = (TextView) FindViewById(viewId);
|
||||||
tv.Text = text;
|
tv.Text = text;
|
||||||
tv.TextChanged += (sender, e) => {State.mEntryModified = true;};
|
tv.TextChanged += (sender, e) => {State.EntryModified = true;};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
{
|
{
|
||||||
if (!mCloseForReload)
|
if (!_closeForReload)
|
||||||
UpdateEntryFromUi(State.mEntry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
|
|
||||||
base.OnPause();
|
base.OnPause();
|
||||||
|
|
||||||
|
@ -1,36 +1,24 @@
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds the state of the EntrryEditActivity. This is required to be able to keep a partially modified entry in memory
|
/// Holds the state of the EntrryEditActivity. This is required to be able to keep a partially modified entry in memory
|
||||||
/// through the App variable. Serializing this state (especially the mEntry/mEntryInDatabase) can be a performance problem
|
/// through the App variable. Serializing this state (especially the Entry/EntryInDatabase) can be a performance problem
|
||||||
/// when there are big attachements.
|
/// when there are big attachements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class EntryEditActivityState
|
internal class EntryEditActivityState
|
||||||
{
|
{
|
||||||
internal PwEntry mEntry, mEntryInDatabase;
|
internal PwEntry Entry, EntryInDatabase;
|
||||||
internal bool mShowPassword = false;
|
internal bool ShowPassword = false;
|
||||||
internal bool mIsNew;
|
internal bool IsNew;
|
||||||
internal PwIcon mSelectedIconID;
|
internal PwIcon SelectedIconId;
|
||||||
internal PwUuid mSelectedCustomIconID = PwUuid.Zero;
|
internal PwUuid SelectedCustomIconId = PwUuid.Zero;
|
||||||
internal bool mSelectedIcon = false;
|
internal bool SelectedIcon = false;
|
||||||
|
|
||||||
internal PwGroup parentGroup;
|
internal PwGroup ParentGroup;
|
||||||
|
|
||||||
internal bool mEntryModified;
|
internal bool EntryModified;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
@ -31,7 +26,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
||||||
public class GeneratePasswordActivity : LockCloseActivity {
|
public class GeneratePasswordActivity : LockCloseActivity {
|
||||||
private int[] BUTTON_IDS = new int[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
private readonly int[] _buttonIds = new[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
||||||
|
|
||||||
public static void Launch(Activity act) {
|
public static void Launch(Activity act) {
|
||||||
Intent i = new Intent(act, typeof(GeneratePasswordActivity));
|
Intent i = new Intent(act, typeof(GeneratePasswordActivity));
|
||||||
@ -43,11 +38,11 @@ namespace keepass2android
|
|||||||
protected override void OnCreate(Bundle savedInstanceState) {
|
protected override void OnCreate(Bundle savedInstanceState) {
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
SetContentView(Resource.Layout.generate_password);
|
SetContentView(Resource.Layout.generate_password);
|
||||||
SetResult(KeePass.EXIT_NORMAL);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
foreach (int id in BUTTON_IDS) {
|
foreach (int id in _buttonIds) {
|
||||||
Button button = (Button) FindViewById(id);
|
Button button = (Button) FindViewById(id);
|
||||||
button.Click += (object sender, EventArgs e) =>
|
button.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
Button b = (Button) sender;
|
Button b = (Button) sender;
|
||||||
|
|
||||||
@ -58,8 +53,8 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button);
|
Button genPassButton = (Button) FindViewById(Resource.Id.generate_password_button);
|
||||||
genPassButton.Click += (object sender, EventArgs e) => {
|
genPassButton.Click += (sender, e) => {
|
||||||
String password = generatePassword();
|
String password = GeneratePassword();
|
||||||
|
|
||||||
EditText txtPassword = (EditText) FindViewById(Resource.Id.password);
|
EditText txtPassword = (EditText) FindViewById(Resource.Id.password);
|
||||||
txtPassword.Text = password;
|
txtPassword.Text = password;
|
||||||
@ -68,20 +63,20 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
View acceptButton = FindViewById(Resource.Id.accept_button);
|
View acceptButton = FindViewById(Resource.Id.accept_button);
|
||||||
acceptButton.Click += (object sender, EventArgs e) => {
|
acceptButton.Click += (sender, e) => {
|
||||||
EditText password = (EditText) FindViewById(Resource.Id.password);
|
EditText password = (EditText) FindViewById(Resource.Id.password);
|
||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.PutExtra("keepass2android.password.generated_password", password.Text);
|
intent.PutExtra("keepass2android.password.generated_password", password.Text);
|
||||||
|
|
||||||
SetResult((Result)EntryEditActivity.RESULT_OK_PASSWORD_GENERATOR, intent);
|
SetResult((Result)EntryEditActivity.ResultOkPasswordGenerator, intent);
|
||||||
|
|
||||||
Finish();
|
Finish();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
View cancelButton = FindViewById(Resource.Id.cancel_button);
|
View cancelButton = FindViewById(Resource.Id.cancel_button);
|
||||||
cancelButton.Click += (object sender, EventArgs e) =>
|
cancelButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
SetResult(Result.Canceled);
|
SetResult(Result.Canceled);
|
||||||
|
|
||||||
@ -90,11 +85,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
EditText txtPasswordToSet = (EditText) FindViewById(Resource.Id.password);
|
EditText txtPasswordToSet = (EditText) FindViewById(Resource.Id.password);
|
||||||
txtPasswordToSet.Text = generatePassword();
|
txtPasswordToSet.Text = GeneratePassword();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generatePassword() {
|
public String GeneratePassword() {
|
||||||
String password = "";
|
String password = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -109,7 +104,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
PasswordGenerator generator = new PasswordGenerator(this);
|
PasswordGenerator generator = new PasswordGenerator(this);
|
||||||
|
|
||||||
password = generator.generatePassword(length,
|
password = generator.GeneratePassword(length,
|
||||||
((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked,
|
((CheckBox) FindViewById(Resource.Id.cb_uppercase)).Checked,
|
||||||
((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked,
|
((CheckBox) FindViewById(Resource.Id.cb_lowercase)).Checked,
|
||||||
((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked,
|
((CheckBox) FindViewById(Resource.Id.cb_digits)).Checked,
|
||||||
|
@ -16,14 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
@ -38,12 +33,12 @@ namespace keepass2android
|
|||||||
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
||||||
public class GroupActivity : GroupBaseActivity {
|
public class GroupActivity : GroupBaseActivity {
|
||||||
|
|
||||||
public const int UNINIT = -1;
|
public const int Uninit = -1;
|
||||||
|
|
||||||
protected bool addGroupEnabled = false;
|
protected bool AddGroupEnabled = false;
|
||||||
protected bool addEntryEnabled = false;
|
protected bool AddEntryEnabled = false;
|
||||||
|
|
||||||
private const String TAG = "Group Activity:";
|
private const String Tag = "Group Activity:";
|
||||||
|
|
||||||
public static void Launch(Activity act, AppTask appTask) {
|
public static void Launch(Activity act, AppTask appTask) {
|
||||||
Launch(act, null, appTask);
|
Launch(act, null, appTask);
|
||||||
@ -51,30 +46,28 @@ namespace keepass2android
|
|||||||
|
|
||||||
public static void Launch (Activity act, PwGroup g, AppTask appTask)
|
public static void Launch (Activity act, PwGroup g, AppTask appTask)
|
||||||
{
|
{
|
||||||
Intent i;
|
|
||||||
|
|
||||||
// Need to use PwDatabase since group may be null
|
// Need to use PwDatabase since group may be null
|
||||||
PwDatabase db = App.getDB ().pm;
|
PwDatabase db = App.Kp2a.GetDb().KpDatabase;
|
||||||
|
|
||||||
if (db == null) {
|
if (db == null) {
|
||||||
// Reached if db is null
|
// Reached if db is null
|
||||||
Log.Debug (TAG, "Tried to launch with null db");
|
Log.Debug (Tag, "Tried to launch with null db");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = new Intent(act, typeof(GroupActivity));
|
Intent i = new Intent(act, typeof(GroupActivity));
|
||||||
|
|
||||||
if ( g != null ) {
|
if ( g != null ) {
|
||||||
i.PutExtra(KEY_ENTRY, g.Uuid.ToHexString());
|
i.PutExtra(KeyEntry, g.Uuid.ToHexString());
|
||||||
}
|
}
|
||||||
appTask.ToIntent(i);
|
appTask.ToIntent(i);
|
||||||
|
|
||||||
act.StartActivityForResult(i,0);
|
act.StartActivityForResult(i,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PwUuid retrieveGroupId(Intent i)
|
protected PwUuid RetrieveGroupId(Intent i)
|
||||||
{
|
{
|
||||||
String uuid = i.GetStringExtra(KEY_ENTRY);
|
String uuid = i.GetStringExtra(KeyEntry);
|
||||||
|
|
||||||
if ( String.IsNullOrEmpty(uuid) ) {
|
if ( String.IsNullOrEmpty(uuid) ) {
|
||||||
return null;
|
return null;
|
||||||
@ -82,10 +75,10 @@ namespace keepass2android
|
|||||||
return new PwUuid(MemUtil.HexStringToByteArray(uuid));
|
return new PwUuid(MemUtil.HexStringToByteArray(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupButtons()
|
protected void SetupButtons()
|
||||||
{
|
{
|
||||||
addGroupEnabled = true;
|
AddGroupEnabled = true;
|
||||||
addEntryEnabled = !mGroup.Uuid.EqualsValue(App.getDB().root.Uuid);
|
AddEntryEnabled = !Group.Uuid.EqualsValue(App.Kp2a.GetDb().Root.Uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnCreate (Bundle savedInstanceState)
|
protected override void OnCreate (Bundle savedInstanceState)
|
||||||
@ -96,60 +89,60 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResult (KeePass.EXIT_NORMAL);
|
SetResult (KeePass.ExitNormal);
|
||||||
|
|
||||||
Log.Warn (TAG, "Creating group view");
|
Log.Warn (Tag, "Creating group view");
|
||||||
Intent intent = Intent;
|
Intent intent = Intent;
|
||||||
|
|
||||||
PwUuid id = retrieveGroupId (intent);
|
PwUuid id = RetrieveGroupId (intent);
|
||||||
|
|
||||||
Database db = App.getDB ();
|
Database db = App.Kp2a.GetDb();
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
mGroup = db.root;
|
Group = db.Root;
|
||||||
} else {
|
} else {
|
||||||
mGroup = db.groups[id];
|
Group = db.Groups[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Warn (TAG, "Retrieved group");
|
Log.Warn (Tag, "Retrieved group");
|
||||||
if (mGroup == null) {
|
if (Group == null) {
|
||||||
Log.Warn (TAG, "Group was null");
|
Log.Warn (Tag, "Group was null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setupButtons ();
|
SetupButtons ();
|
||||||
|
|
||||||
if (addGroupEnabled && addEntryEnabled) {
|
if (AddGroupEnabled && AddEntryEnabled) {
|
||||||
SetContentView (new GroupAddEntryView (this));
|
SetContentView (new GroupAddEntryView (this));
|
||||||
} else if (addGroupEnabled) {
|
} else if (AddGroupEnabled) {
|
||||||
SetContentView (new GroupRootView (this));
|
SetContentView (new GroupRootView (this));
|
||||||
} else if (addEntryEnabled) {
|
} else if (AddEntryEnabled) {
|
||||||
throw new Exception ("This mode is not supported.");
|
throw new Exception ("This mode is not supported.");
|
||||||
} else {
|
} else {
|
||||||
SetContentView (new GroupViewOnlyView (this));
|
SetContentView (new GroupViewOnlyView (this));
|
||||||
}
|
}
|
||||||
if (addGroupEnabled) {
|
if (AddGroupEnabled) {
|
||||||
// Add Group button
|
// Add Group button
|
||||||
View addGroup = FindViewById (Resource.Id.add_group);
|
View addGroup = FindViewById (Resource.Id.add_group);
|
||||||
addGroup.Click += (object sender, EventArgs e) => {
|
addGroup.Click += (sender, e) => {
|
||||||
GroupEditActivity.Launch (this, mGroup);
|
GroupEditActivity.Launch (this, Group);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addEntryEnabled) {
|
if (AddEntryEnabled) {
|
||||||
// Add Entry button
|
// Add Entry button
|
||||||
View addEntry = FindViewById (Resource.Id.add_entry);
|
View addEntry = FindViewById (Resource.Id.add_entry);
|
||||||
addEntry.Click += (object sender, EventArgs e) => {
|
addEntry.Click += (sender, e) => {
|
||||||
EntryEditActivity.Launch (this, mGroup, mAppTask);
|
EntryEditActivity.Launch (this, Group, AppTask);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setGroupTitle();
|
SetGroupTitle();
|
||||||
setGroupIcon();
|
SetGroupIcon();
|
||||||
|
|
||||||
ListAdapter = new PwGroupListAdapter(this, mGroup);
|
ListAdapter = new PwGroupListAdapter(this, Group);
|
||||||
RegisterForContextMenu(ListView);
|
RegisterForContextMenu(ListView);
|
||||||
Log.Warn(TAG, "Finished creating group");
|
Log.Warn(Tag, "Finished creating group");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,12 +157,12 @@ namespace keepass2android
|
|||||||
public override void OnBackPressed()
|
public override void OnBackPressed()
|
||||||
{
|
{
|
||||||
base.OnBackPressed();
|
base.OnBackPressed();
|
||||||
if ((mGroup != null) && (mGroup.ParentGroup != null))
|
if ((Group != null) && (Group.ParentGroup != null))
|
||||||
OverridePendingTransition(Resource.Animation.anim_enter_back, Resource.Animation.anim_leave_back);
|
OverridePendingTransition(Resource.Animation.anim_enter_back, Resource.Animation.anim_leave_back);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnContextItemSelected(IMenuItem item) {
|
public override bool OnContextItemSelected(IMenuItem item) {
|
||||||
Android.Widget.AdapterView.AdapterContextMenuInfo acmi = (Android.Widget.AdapterView.AdapterContextMenuInfo)item.MenuInfo;
|
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.MenuInfo;
|
||||||
ClickView cv = (ClickView) acmi.TargetView;
|
ClickView cv = (ClickView) acmi.TargetView;
|
||||||
|
|
||||||
return cv.OnContextItemSelected(item);
|
return cv.OnContextItemSelected(item);
|
||||||
@ -180,18 +173,19 @@ namespace keepass2android
|
|||||||
switch (resultCode)
|
switch (resultCode)
|
||||||
{
|
{
|
||||||
case Result.Ok:
|
case Result.Ok:
|
||||||
String GroupName = data.Extras.GetString(GroupEditActivity.KEY_NAME);
|
String groupName = data.Extras.GetString(GroupEditActivity.KeyName);
|
||||||
int GroupIconID = data.Extras.GetInt(GroupEditActivity.KEY_ICON_ID);
|
int groupIconId = data.Extras.GetInt(GroupEditActivity.KeyIconId);
|
||||||
GroupBaseActivity act = this;
|
GroupBaseActivity act = this;
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
AddGroup task = AddGroup.getInstance(this, App.getDB(), GroupName, GroupIconID, mGroup, new RefreshTask(handler, this), false);
|
AddGroup task = AddGroup.GetInstance(this, App.Kp2a.GetDb(), groupName, groupIconId, Group, new RefreshTask(handler, this), false);
|
||||||
ProgressTask pt = new ProgressTask(act, task, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, act, task, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Result.Canceled:
|
case Result.Canceled:
|
||||||
default:
|
break;
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
default:
|
||||||
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,6 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
@ -35,19 +31,20 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
|
|
||||||
public abstract class GroupBaseActivity : LockCloseListActivity {
|
public abstract class GroupBaseActivity : LockCloseListActivity {
|
||||||
public const String KEY_ENTRY = "entry";
|
public const String KeyEntry = "entry";
|
||||||
public const String KEY_MODE = "mode";
|
public const String KeyMode = "mode";
|
||||||
|
|
||||||
public virtual void LaunchActivityForEntry(KeePassLib.PwEntry pwEntry, int pos)
|
public virtual void LaunchActivityForEntry(PwEntry pwEntry, int pos)
|
||||||
{
|
{
|
||||||
EntryActivity.Launch(this, pwEntry, pos, mAppTask);
|
EntryActivity.Launch(this, pwEntry, pos, AppTask);
|
||||||
}
|
}
|
||||||
public GroupBaseActivity ()
|
|
||||||
|
protected GroupBaseActivity ()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupBaseActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
protected GroupBaseActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -56,7 +53,7 @@ namespace keepass2android
|
|||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
mAppTask.ToBundle(outState);
|
AppTask.ToBundle(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,24 +61,24 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
if (resultCode == KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE)
|
if (resultCode == KeePass.ExitCloseAfterTaskComplete)
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE);
|
SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISharedPreferences prefs;
|
private ISharedPreferences _prefs;
|
||||||
|
|
||||||
protected PwGroup mGroup;
|
protected PwGroup Group;
|
||||||
|
|
||||||
internal AppTask mAppTask;
|
internal AppTask AppTask;
|
||||||
|
|
||||||
protected override void OnResume() {
|
protected override void OnResume() {
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
refreshIfDirty();
|
RefreshIfDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnSearchRequested()
|
public override bool OnSearchRequested()
|
||||||
@ -90,10 +87,10 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshIfDirty() {
|
public void RefreshIfDirty() {
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
if ( db.dirty.Contains(mGroup) ) {
|
if ( db.Dirty.Contains(Group) ) {
|
||||||
db.dirty.Remove(mGroup);
|
db.Dirty.Remove(Group);
|
||||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();
|
||||||
|
|
||||||
@ -103,7 +100,7 @@ namespace keepass2android
|
|||||||
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||||
base.OnListItemClick(l, v, position, id);
|
base.OnListItemClick(l, v, position, id);
|
||||||
|
|
||||||
Android.Widget.IListAdapter adapt = ListAdapter;
|
IListAdapter adapt = ListAdapter;
|
||||||
ClickView cv = (ClickView) adapt.GetView(position, null, null);
|
ClickView cv = (ClickView) adapt.GetView(position, null, null);
|
||||||
cv.OnClick();
|
cv.OnClick();
|
||||||
|
|
||||||
@ -112,24 +109,24 @@ namespace keepass2android
|
|||||||
protected override void OnCreate(Bundle savedInstanceState) {
|
protected override void OnCreate(Bundle savedInstanceState) {
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
mAppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||||
|
|
||||||
// Likely the app has been killed exit the activity
|
// Likely the app has been killed exit the activity
|
||||||
if ( ! App.getDB().Loaded ) {
|
if ( ! App.Kp2a.GetDb().Loaded ) {
|
||||||
Finish();
|
Finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
_prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
|
|
||||||
SetContentView(new GroupViewOnlyView(this));
|
SetContentView(new GroupViewOnlyView(this));
|
||||||
SetResult(KeePass.EXIT_NORMAL);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
styleScrollBars();
|
StyleScrollBars();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void styleScrollBars() {
|
protected void StyleScrollBars() {
|
||||||
ListView lv = ListView;
|
ListView lv = ListView;
|
||||||
lv.ScrollBarStyle =ScrollbarStyles.InsideInset;
|
lv.ScrollBarStyle =ScrollbarStyles.InsideInset;
|
||||||
lv.TextFilterEnabled = true;
|
lv.TextFilterEnabled = true;
|
||||||
@ -137,11 +134,11 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setGroupTitle()
|
protected void SetGroupTitle()
|
||||||
{
|
{
|
||||||
String name = mGroup.Name;
|
String name = Group.Name;
|
||||||
String titleText;
|
String titleText;
|
||||||
bool clickable = (mGroup != null) && (mGroup.IsVirtual == false) && (mGroup.ParentGroup != null);
|
bool clickable = (Group != null) && (Group.IsVirtual == false) && (Group.ParentGroup != null);
|
||||||
if (!String.IsNullOrEmpty(name))
|
if (!String.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
titleText = name;
|
titleText = name;
|
||||||
@ -154,14 +151,14 @@ namespace keepass2android
|
|||||||
Button tv = (Button)FindViewById(Resource.Id.group_name);
|
Button tv = (Button)FindViewById(Resource.Id.group_name);
|
||||||
if (tv != null)
|
if (tv != null)
|
||||||
{
|
{
|
||||||
if (mGroup != null)
|
if (Group != null)
|
||||||
{
|
{
|
||||||
tv.Text = titleText;
|
tv.Text = titleText;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickable)
|
if (clickable)
|
||||||
{
|
{
|
||||||
tv.Click += (object sender, EventArgs e) =>
|
tv.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
};
|
};
|
||||||
@ -181,9 +178,9 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setGroupIcon() {
|
protected void SetGroupIcon() {
|
||||||
if (mGroup != null) {
|
if (Group != null) {
|
||||||
Drawable drawable = App.getDB().drawFactory.getIconDrawable(Resources, App.getDB().pm, mGroup.IconId, mGroup.CustomIconUuid);
|
Drawable drawable = App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(Resources, App.Kp2a.GetDb().KpDatabase, Group.IconId, Group.CustomIconUuid);
|
||||||
ImageView iv = (ImageView) FindViewById(Resource.Id.icon);
|
ImageView iv = (ImageView) FindViewById(Resource.Id.icon);
|
||||||
if (iv != null)
|
if (iv != null)
|
||||||
iv.SetImageDrawable(drawable);
|
iv.SetImageDrawable(drawable);
|
||||||
@ -206,8 +203,8 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSortMenuText(IMenu menu) {
|
private void SetSortMenuText(IMenu menu) {
|
||||||
bool sortByName = prefs.GetBoolean(GetString(Resource.String.sort_key), Resources.GetBoolean(Resource.Boolean.sort_default));
|
bool sortByName = _prefs.GetBoolean(GetString(Resource.String.sort_key), Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||||
|
|
||||||
int resId;
|
int resId;
|
||||||
if ( sortByName ) {
|
if ( sortByName ) {
|
||||||
@ -225,7 +222,7 @@ namespace keepass2android
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSortMenuText(menu);
|
SetSortMenuText(menu);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -242,8 +239,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_lock:
|
case Resource.Id.menu_lock:
|
||||||
App.setShutdown();
|
App.Kp2a.SetShutdown();
|
||||||
SetResult(KeePass.EXIT_LOCK);
|
SetResult(KeePass.ExitLock);
|
||||||
Finish();
|
Finish();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -257,11 +254,11 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_change_master_key:
|
case Resource.Id.menu_change_master_key:
|
||||||
setPassword();
|
SetPassword();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_sort:
|
case Resource.Id.menu_sort:
|
||||||
toggleSort();
|
ToggleSort();
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_rate:
|
case Resource.Id.menu_rate:
|
||||||
try {
|
try {
|
||||||
@ -297,22 +294,22 @@ namespace keepass2android
|
|||||||
return base.OnOptionsItemSelected(item);
|
return base.OnOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleSort() {
|
private void ToggleSort() {
|
||||||
// Toggle setting
|
// Toggle setting
|
||||||
String sortKey = GetString(Resource.String.sort_key);
|
String sortKey = GetString(Resource.String.sort_key);
|
||||||
bool sortByName = prefs.GetBoolean(sortKey, Resources.GetBoolean(Resource.Boolean.sort_default));
|
bool sortByName = _prefs.GetBoolean(sortKey, Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||||
ISharedPreferencesEditor editor = prefs.Edit();
|
ISharedPreferencesEditor editor = _prefs.Edit();
|
||||||
editor.PutBoolean(sortKey, ! sortByName);
|
editor.PutBoolean(sortKey, ! sortByName);
|
||||||
EditorCompat.apply(editor);
|
EditorCompat.Apply(editor);
|
||||||
|
|
||||||
// Refresh menu titles
|
// Refresh menu titles
|
||||||
ActivityCompat.invalidateOptionsMenu(this);
|
ActivityCompat.InvalidateOptionsMenu(this);
|
||||||
|
|
||||||
// Mark all groups as dirty now to refresh them on load
|
// Mark all groups as dirty now to refresh them on load
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
db.markAllGroupsAsDirty();
|
db.MarkAllGroupsAsDirty();
|
||||||
// We'll manually refresh this group so we can remove it
|
// We'll manually refresh this group so we can remove it
|
||||||
db.dirty.Remove(mGroup);
|
db.Dirty.Remove(Group);
|
||||||
|
|
||||||
// Tell the adapter to refresh it's list
|
// Tell the adapter to refresh it's list
|
||||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
||||||
@ -320,43 +317,43 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPassword() {
|
private void SetPassword() {
|
||||||
SetPasswordDialog dialog = new SetPasswordDialog(this);
|
SetPasswordDialog dialog = new SetPasswordDialog(this);
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RefreshTask : OnFinish {
|
public class RefreshTask : OnFinish {
|
||||||
GroupBaseActivity act;
|
readonly GroupBaseActivity _act;
|
||||||
public RefreshTask(Handler handler, GroupBaseActivity act):base(handler) {
|
public RefreshTask(Handler handler, GroupBaseActivity act):base(handler) {
|
||||||
this.act = act;
|
_act = act;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess) {
|
if ( Success) {
|
||||||
act.refreshIfDirty();
|
_act.RefreshIfDirty();
|
||||||
} else {
|
} else {
|
||||||
displayMessage(act);
|
DisplayMessage(_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class AfterDeleteGroup : OnFinish {
|
public class AfterDeleteGroup : OnFinish {
|
||||||
GroupBaseActivity act;
|
readonly GroupBaseActivity _act;
|
||||||
|
|
||||||
public AfterDeleteGroup(Handler handler, GroupBaseActivity act):base(handler) {
|
public AfterDeleteGroup(Handler handler, GroupBaseActivity act):base(handler) {
|
||||||
this.act = act;
|
_act = act;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess) {
|
if ( Success) {
|
||||||
act.refreshIfDirty();
|
_act.RefreshIfDirty();
|
||||||
} else {
|
} else {
|
||||||
mHandler.Post( () => {
|
Handler.Post( () => {
|
||||||
Toast.MakeText(act, "Unrecoverable error: " + mMessage, ToastLength.Long).Show();
|
Toast.MakeText(_act, "Unrecoverable error: " + Message, ToastLength.Long).Show();
|
||||||
});
|
});
|
||||||
|
|
||||||
App.setShutdown();
|
App.Kp2a.SetShutdown();
|
||||||
act.Finish();
|
_act.Finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,15 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
|
|
||||||
@ -33,18 +27,18 @@ namespace keepass2android
|
|||||||
[Activity (Label = "@string/app_name", Theme="@style/Dialog")]
|
[Activity (Label = "@string/app_name", Theme="@style/Dialog")]
|
||||||
public class GroupEditActivity : LifecycleDebugActivity
|
public class GroupEditActivity : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
public const String KEY_PARENT = "parent";
|
public const String KeyParent = "parent";
|
||||||
public const String KEY_NAME = "name";
|
public const String KeyName = "name";
|
||||||
public const String KEY_ICON_ID = "icon_id";
|
public const String KeyIconId = "icon_id";
|
||||||
|
|
||||||
private int mSelectedIconID;
|
private int _selectedIconId;
|
||||||
|
|
||||||
public static void Launch(Activity act, PwGroup pw)
|
public static void Launch(Activity act, PwGroup pw)
|
||||||
{
|
{
|
||||||
Intent i = new Intent(act, typeof(GroupEditActivity));
|
Intent i = new Intent(act, typeof(GroupEditActivity));
|
||||||
|
|
||||||
PwGroup parent = pw;
|
PwGroup parent = pw;
|
||||||
i.PutExtra(KEY_PARENT, parent.Uuid.ToHexString());
|
i.PutExtra(KeyParent, parent.Uuid.ToHexString());
|
||||||
|
|
||||||
act.StartActivityForResult(i, 0);
|
act.StartActivityForResult(i, 0);
|
||||||
}
|
}
|
||||||
@ -56,23 +50,23 @@ namespace keepass2android
|
|||||||
SetTitle (Resource.String.add_group_title);
|
SetTitle (Resource.String.add_group_title);
|
||||||
|
|
||||||
ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button);
|
ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button);
|
||||||
iconButton.Click += (object sender, EventArgs e) =>
|
iconButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
IconPickerActivity.Launch (this);
|
IconPickerActivity.Launch (this);
|
||||||
};
|
};
|
||||||
mSelectedIconID = (int) PwIcon.FolderOpen;
|
_selectedIconId = (int) PwIcon.FolderOpen;
|
||||||
iconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID));
|
iconButton.SetImageResource(Icons.IconToResId((PwIcon)_selectedIconId));
|
||||||
|
|
||||||
Button okButton = (Button)FindViewById (Resource.Id.ok);
|
Button okButton = (Button)FindViewById (Resource.Id.ok);
|
||||||
okButton.Click += (object sender, EventArgs e) => {
|
okButton.Click += (sender, e) => {
|
||||||
TextView nameField = (TextView)FindViewById (Resource.Id.group_name);
|
TextView nameField = (TextView)FindViewById (Resource.Id.group_name);
|
||||||
String name = nameField.Text;
|
String name = nameField.Text;
|
||||||
|
|
||||||
if (name.Length > 0) {
|
if (name.Length > 0) {
|
||||||
Intent intent = new Intent ();
|
Intent intent = new Intent ();
|
||||||
|
|
||||||
intent.PutExtra (KEY_NAME, name);
|
intent.PutExtra (KeyName, name);
|
||||||
intent.PutExtra (KEY_ICON_ID, mSelectedIconID);
|
intent.PutExtra (KeyIconId, _selectedIconId);
|
||||||
SetResult (Result.Ok, intent);
|
SetResult (Result.Ok, intent);
|
||||||
|
|
||||||
Finish ();
|
Finish ();
|
||||||
@ -83,7 +77,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
Button cancel = (Button)FindViewById (Resource.Id.cancel);
|
Button cancel = (Button)FindViewById (Resource.Id.cancel);
|
||||||
cancel.Click += (object sender, EventArgs e) => {
|
cancel.Click += (sender, e) => {
|
||||||
Intent intent = new Intent ();
|
Intent intent = new Intent ();
|
||||||
SetResult (Result.Canceled, intent);
|
SetResult (Result.Canceled, intent);
|
||||||
|
|
||||||
@ -95,12 +89,10 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
switch ((int)resultCode)
|
switch ((int)resultCode)
|
||||||
{
|
{
|
||||||
case EntryEditActivity.RESULT_OK_ICON_PICKER:
|
case EntryEditActivity.ResultOkIconPicker:
|
||||||
mSelectedIconID = data.Extras.GetInt(IconPickerActivity.KEY_ICON_ID);
|
_selectedIconId = data.Extras.GetInt(IconPickerActivity.KeyIconId);
|
||||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||||
currIconButton.SetImageResource(Icons.iconToResId((PwIcon)mSelectedIconID));
|
currIconButton.SetImageResource(Icons.IconToResId((PwIcon)_selectedIconId));
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
@ -32,8 +27,8 @@ namespace keepass2android
|
|||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
||||||
public class IconPickerActivity : LockCloseActivity
|
public class IconPickerActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
public const String KEY_ICON_ID = "icon_id";
|
public const String KeyIconId = "icon_id";
|
||||||
public const String KEY_CUSTOM_ICON_ID = "custom_icon_id";
|
public const String KeyCustomIconId = "custom_icon_id";
|
||||||
|
|
||||||
public static void Launch(Activity act)
|
public static void Launch(Activity act)
|
||||||
{
|
{
|
||||||
@ -47,14 +42,14 @@ namespace keepass2android
|
|||||||
SetContentView(Resource.Layout.icon_picker);
|
SetContentView(Resource.Layout.icon_picker);
|
||||||
|
|
||||||
GridView currIconGridView = (GridView)FindViewById(Resource.Id.IconGridView);
|
GridView currIconGridView = (GridView)FindViewById(Resource.Id.IconGridView);
|
||||||
currIconGridView.Adapter = new ImageAdapter(this, this);
|
currIconGridView.Adapter = new ImageAdapter(this);
|
||||||
|
|
||||||
currIconGridView.ItemClick += (sender, e) => {
|
currIconGridView.ItemClick += (sender, e) => {
|
||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
|
|
||||||
intent.PutExtra(KEY_ICON_ID, e.Position);
|
intent.PutExtra(KeyIconId, e.Position);
|
||||||
SetResult((Result)EntryEditActivity.RESULT_OK_ICON_PICKER, intent);
|
SetResult((Result)EntryEditActivity.ResultOkIconPicker, intent);
|
||||||
|
|
||||||
Finish();
|
Finish();
|
||||||
};
|
};
|
||||||
@ -62,14 +57,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
public class ImageAdapter : BaseAdapter
|
public class ImageAdapter : BaseAdapter
|
||||||
{
|
{
|
||||||
Context mContext;
|
readonly IconPickerActivity _act;
|
||||||
|
|
||||||
IconPickerActivity act;
|
|
||||||
|
|
||||||
public ImageAdapter(Context c, IconPickerActivity act)
|
public ImageAdapter(IconPickerActivity act)
|
||||||
{
|
{
|
||||||
mContext = c;
|
_act = act;
|
||||||
this.act = act;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Count
|
public override int Count
|
||||||
@ -77,7 +69,7 @@ namespace keepass2android
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
/* Return number of KeePass icons */
|
/* Return number of KeePass icons */
|
||||||
return Icons.count();
|
return Icons.Count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +88,7 @@ namespace keepass2android
|
|||||||
View currView;
|
View currView;
|
||||||
if(convertView == null)
|
if(convertView == null)
|
||||||
{
|
{
|
||||||
LayoutInflater li = (LayoutInflater) act.GetSystemService(Context.LayoutInflaterService);
|
LayoutInflater li = (LayoutInflater) _act.GetSystemService(LayoutInflaterService);
|
||||||
currView = li.Inflate(Resource.Layout.icon, null);
|
currView = li.Inflate(Resource.Layout.icon, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -107,7 +99,7 @@ namespace keepass2android
|
|||||||
TextView tv = (TextView) currView.FindViewById(Resource.Id.icon_text);
|
TextView tv = (TextView) currView.FindViewById(Resource.Id.icon_text);
|
||||||
tv.Text = "" + position;
|
tv.Text = "" + position;
|
||||||
ImageView iv = (ImageView) currView.FindViewById(Resource.Id.icon_image);
|
ImageView iv = (ImageView) currView.FindViewById(Resource.Id.icon_image);
|
||||||
iv.SetImageResource(Icons.iconToResId((KeePassLib.PwIcon)position));
|
iv.SetImageResource(Icons.IconToResId((KeePassLib.PwIcon)position));
|
||||||
|
|
||||||
return currView;
|
return currView;
|
||||||
}
|
}
|
||||||
|
@ -18,41 +18,38 @@ using System;
|
|||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
|
|
||||||
using keepass2android.view;
|
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.Text;
|
using Android.Text;
|
||||||
using Android.Text.Util;
|
|
||||||
using Android.Text.Method;
|
using Android.Text.Method;
|
||||||
using KeePassLib.Serialization;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Launcher activity of Keepass2Android. This activity usually forwards to FileSelect but may show the revision dialog after installation or updates.
|
||||||
|
/// </summary>
|
||||||
[Activity (Label = AppNames.AppName, MainLauncher = true, Theme="@style/Base")]
|
[Activity (Label = AppNames.AppName, MainLauncher = true, Theme="@style/Base")]
|
||||||
public class KeePass : LifecycleDebugActivity
|
public class KeePass : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
public const Android.App.Result EXIT_NORMAL = Android.App.Result.FirstUser;
|
public const Result ExitNormal = Result.FirstUser;
|
||||||
public const Android.App.Result EXIT_LOCK = Android.App.Result.FirstUser+1;
|
public const Result ExitLock = Result.FirstUser+1;
|
||||||
public const Android.App.Result EXIT_REFRESH = Android.App.Result.FirstUser+2;
|
public const Result ExitRefresh = Result.FirstUser+2;
|
||||||
public const Android.App.Result EXIT_REFRESH_TITLE = Android.App.Result.FirstUser+3;
|
public const Result ExitRefreshTitle = Result.FirstUser+3;
|
||||||
public const Android.App.Result EXIT_FORCE_LOCK = Android.App.Result.FirstUser+4;
|
public const Result ExitForceLock = Result.FirstUser+4;
|
||||||
public const Android.App.Result EXIT_QUICK_UNLOCK = Android.App.Result.FirstUser+5;
|
public const Result ExitQuickUnlock = Result.FirstUser+5;
|
||||||
public const Android.App.Result EXIT_CLOSE_AFTER_TASK_COMPLETE = Android.App.Result.FirstUser+6;
|
public const Result ExitCloseAfterTaskComplete = Result.FirstUser+6;
|
||||||
public const Android.App.Result EXIT_CHANGE_DB = Android.App.Result.FirstUser+7;
|
public const Result ExitChangeDb = Result.FirstUser+7;
|
||||||
public const Android.App.Result EXIT_FORCE_LOCK_AND_CHANGE_DB = Android.App.Result.FirstUser+8;
|
public const Result ExitForceLockAndChangeDb = Result.FirstUser+8;
|
||||||
public const Android.App.Result EXIT_RELOAD_DB = Android.App.Result.FirstUser+9;
|
public const Result ExitReloadDb = Result.FirstUser+9;
|
||||||
|
|
||||||
AppTask mAppTask;
|
AppTask _appTask;
|
||||||
|
|
||||||
protected override void OnCreate (Bundle bundle)
|
protected override void OnCreate (Bundle bundle)
|
||||||
{
|
{
|
||||||
base.OnCreate (bundle);
|
base.OnCreate (bundle);
|
||||||
mAppTask = AppTask.GetTaskInOnCreate(bundle, Intent);
|
_appTask = AppTask.GetTaskInOnCreate(bundle, Intent);
|
||||||
Android.Util.Log.Debug("DEBUG","KeePass.OnCreate");
|
Android.Util.Log.Debug("DEBUG","KeePass.OnCreate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
ISharedPreferencesEditor edit = prefs.Edit();
|
ISharedPreferencesEditor edit = prefs.Edit();
|
||||||
edit.PutInt(GetString(Resource.String.LastInfoVersionCode_key), packageInfo.VersionCode);
|
edit.PutInt(GetString(Resource.String.LastInfoVersionCode_key), packageInfo.VersionCode);
|
||||||
EditorCompat.apply(edit);
|
EditorCompat.Apply(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (PackageManager.NameNotFoundException)
|
} catch (PackageManager.NameNotFoundException)
|
||||||
@ -102,13 +99,13 @@ namespace keepass2android
|
|||||||
GetString(Resource.String.ChangeLog)
|
GetString(Resource.String.ChangeLog)
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.SetPositiveButton(Android.Resource.String.Ok,new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt)=>{}));
|
builder.SetPositiveButton(Android.Resource.String.Ok,(dlgSender, dlgEvt)=>{});
|
||||||
|
|
||||||
builder.SetMessage("temp");
|
builder.SetMessage("temp");
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
dialog.DismissEvent += (object sender, EventArgs e) =>
|
dialog.DismissEvent += (sender, e) =>
|
||||||
{
|
{
|
||||||
startFileSelect();
|
StartFileSelect();
|
||||||
};
|
};
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
TextView message = (TextView) dialog.FindViewById(Android.Resource.Id.Message);
|
TextView message = (TextView) dialog.FindViewById(Android.Resource.Id.Message);
|
||||||
@ -121,7 +118,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
startFileSelect();
|
StartFileSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -159,13 +156,13 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startFileSelect() {
|
private void StartFileSelect() {
|
||||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||||
//TEST Intent intent = new Intent(this, typeof(EntryActivity));
|
//TEST Intent intent = new Intent(this, typeof(EntryActivity));
|
||||||
//Intent intent = new Intent(this, typeof(SearchActivity));
|
//Intent intent = new Intent(this, typeof(SearchActivity));
|
||||||
//Intent intent = new Intent(this, typeof(QuickUnlock));
|
//Intent intent = new Intent(this, typeof(QuickUnlock));
|
||||||
|
|
||||||
mAppTask.ToIntent(intent);
|
_appTask.ToIntent(intent);
|
||||||
|
|
||||||
|
|
||||||
StartActivityForResult(intent, 0);
|
StartActivityForResult(intent, 0);
|
||||||
|
@ -16,40 +16,33 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class LifecycleDebugActivity : Activity
|
public abstract class LifecycleDebugActivity : Activity
|
||||||
{
|
{
|
||||||
public LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
protected LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LifecycleDebugActivity()
|
protected LifecycleDebugActivity()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string className = null;
|
string _className;
|
||||||
string ClassName
|
string ClassName
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
if (className == null)
|
if (_className == null)
|
||||||
className = this.GetType().Name;
|
_className = GetType().Name;
|
||||||
return className;
|
return _className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,29 +15,23 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for activities displaying sensitive information.
|
||||||
|
/// </summary>
|
||||||
|
/// Checks in OnResume whether the timeout occured and the database must be locked/closed.
|
||||||
public class LockCloseActivity : LockingActivity {
|
public class LockCloseActivity : LockingActivity {
|
||||||
|
|
||||||
IOConnectionInfo mIoc;
|
IOConnectionInfo _ioc;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
mIoc = App.getDB().mIoc;
|
_ioc = App.Kp2a.GetDb().Ioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,12 +39,14 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
if (TimeoutHelper.checkShutdown(this, mIoc))
|
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
App.getDB().CheckForOpenFileChanged(this);
|
App.Kp2a.CheckForOpenFileChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,33 +16,28 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for list activities displaying sensitive information.
|
||||||
|
/// </summary>
|
||||||
|
/// Checks in OnResume whether the timeout occured and the database must be locked/closed.
|
||||||
public class LockCloseListActivity : LockingListActivity {
|
public class LockCloseListActivity : LockingListActivity {
|
||||||
public LockCloseListActivity()
|
public LockCloseListActivity()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IOConnectionInfo mIoc;
|
IOConnectionInfo _ioc;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
mIoc = App.getDB().mIoc;
|
_ioc = App.Kp2a.GetDb().Ioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LockCloseListActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
public LockCloseListActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
@ -55,10 +50,10 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
if (TimeoutHelper.checkShutdown(this, mIoc))
|
if (TimeoutHelper.CheckShutdown(this, _ioc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
App.getDB().CheckForOpenFileChanged(this);
|
App.Kp2a.CheckForOpenFileChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,20 +16,13 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
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.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for activities. Notifies the TimeoutHelper whether the app is active or not.
|
||||||
|
/// </summary>
|
||||||
public class LockingActivity : LifecycleDebugActivity {
|
public class LockingActivity : LifecycleDebugActivity {
|
||||||
|
|
||||||
public LockingActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
public LockingActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
@ -45,7 +38,7 @@ namespace keepass2android
|
|||||||
protected override void OnPause() {
|
protected override void OnPause() {
|
||||||
base.OnPause();
|
base.OnPause();
|
||||||
|
|
||||||
TimeoutHelper.pause(this);
|
TimeoutHelper.Pause(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDestroy()
|
protected override void OnDestroy()
|
||||||
@ -57,7 +50,7 @@ namespace keepass2android
|
|||||||
protected override void OnResume() {
|
protected override void OnResume() {
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
TimeoutHelper.resume(this);
|
TimeoutHelper.Resume(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -34,18 +24,18 @@ namespace keepass2android
|
|||||||
public class LockingClosePreferenceActivity : LockingPreferenceActivity {
|
public class LockingClosePreferenceActivity : LockingPreferenceActivity {
|
||||||
|
|
||||||
|
|
||||||
IOConnectionInfo mIoc;
|
IOConnectionInfo _ioc;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
mIoc = App.getDB().mIoc;
|
_ioc = App.Kp2a.GetDb().Ioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume() {
|
protected override void OnResume() {
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
TimeoutHelper.checkShutdown(this, mIoc);
|
TimeoutHelper.CheckShutdown(this, _ioc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,20 +16,15 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for list activities. Notifies the TimeoutHelper whether the app is active or not.
|
||||||
|
/// </summary>
|
||||||
public class LockingListActivity : ListActivity {
|
public class LockingListActivity : ListActivity {
|
||||||
|
|
||||||
|
|
||||||
@ -43,20 +38,20 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string className = null;
|
string _className;
|
||||||
string ClassName
|
string ClassName
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
if (className == null)
|
if (_className == null)
|
||||||
className = this.GetType().Name;
|
_className = GetType().Name;
|
||||||
return className;
|
return _className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
TimeoutHelper.resume(this);
|
TimeoutHelper.Resume(this);
|
||||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +77,7 @@ namespace keepass2android
|
|||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
{
|
{
|
||||||
base.OnPause();
|
base.OnPause();
|
||||||
TimeoutHelper.pause(this);
|
TimeoutHelper.Pause(this);
|
||||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,16 +16,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -43,20 +35,20 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string className = null;
|
string _className = null;
|
||||||
string ClassName
|
string ClassName
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
if (className == null)
|
if (_className == null)
|
||||||
className = this.GetType().Name;
|
_className = this.GetType().Name;
|
||||||
return className;
|
return _className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
TimeoutHelper.resume(this);
|
TimeoutHelper.Resume(this);
|
||||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
Android.Util.Log.Debug("DEBUG",ClassName+".OnResume");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +74,7 @@ namespace keepass2android
|
|||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
{
|
{
|
||||||
base.OnPause();
|
base.OnPause();
|
||||||
TimeoutHelper.pause(this);
|
TimeoutHelper.Pause(this);
|
||||||
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
Android.Util.Log.Debug("DEBUG",ClassName+".OnPause");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,10 +16,6 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
@ -31,10 +27,8 @@ using Android.Preferences;
|
|||||||
using Java.IO;
|
using Java.IO;
|
||||||
using Android.Text;
|
using Android.Text;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.Text.Method;
|
|
||||||
using KeePassLib.Keys;
|
using KeePassLib.Keys;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
using Android.Views.InputMethods;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@ -43,22 +37,22 @@ namespace keepass2android
|
|||||||
Theme="@style/Base")]
|
Theme="@style/Base")]
|
||||||
|
|
||||||
public class PasswordActivity : LockingActivity {
|
public class PasswordActivity : LockingActivity {
|
||||||
bool mShowPassword = false;
|
bool _showPassword;
|
||||||
|
|
||||||
public const String KEY_DEFAULT_FILENAME = "defaultFileName";
|
public const String KeyDefaultFilename = "defaultFileName";
|
||||||
|
|
||||||
public const String KEY_FILENAME = "fileName";
|
public const String KeyFilename = "fileName";
|
||||||
private const String KEY_KEYFILE = "keyFile";
|
private const String KeyKeyfile = "keyFile";
|
||||||
private const String KEY_SERVERUSERNAME = "serverCredUser";
|
private const String KeyServerusername = "serverCredUser";
|
||||||
private const String KEY_SERVERPASSWORD = "serverCredPwd";
|
private const String KeyServerpassword = "serverCredPwd";
|
||||||
private const String KEY_SERVERCREDMODE = "serverCredRememberMode";
|
private const String KeyServercredmode = "serverCredRememberMode";
|
||||||
|
|
||||||
private const String VIEW_INTENT = "android.intent.action.VIEW";
|
private const String ViewIntent = "android.intent.action.VIEW";
|
||||||
|
|
||||||
private IOConnectionInfo mIoConnection;
|
private IOConnectionInfo _ioConnection;
|
||||||
private String mKeyFile;
|
private String _keyFile;
|
||||||
private bool mRememberKeyfile;
|
private bool _rememberKeyfile;
|
||||||
ISharedPreferences prefs;
|
ISharedPreferences _prefs;
|
||||||
|
|
||||||
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
@ -72,31 +66,31 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void PutIoConnectionToIntent(IOConnectionInfo ioc, Android.Content.Intent i)
|
static void PutIoConnectionToIntent(IOConnectionInfo ioc, Intent i)
|
||||||
{
|
{
|
||||||
i.PutExtra(KEY_FILENAME, ioc.Path);
|
i.PutExtra(KeyFilename, ioc.Path);
|
||||||
i.PutExtra(KEY_SERVERUSERNAME, ioc.UserName);
|
i.PutExtra(KeyServerusername, ioc.UserName);
|
||||||
i.PutExtra(KEY_SERVERPASSWORD, ioc.Password);
|
i.PutExtra(KeyServerpassword, ioc.Password);
|
||||||
i.PutExtra(KEY_SERVERCREDMODE, (int)ioc.CredSaveMode);
|
i.PutExtra(KeyServercredmode, (int)ioc.CredSaveMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i)
|
public static void SetIoConnectionFromIntent(IOConnectionInfo ioc, Intent i)
|
||||||
{
|
{
|
||||||
ioc.Path = i.GetStringExtra(KEY_FILENAME);
|
ioc.Path = i.GetStringExtra(KeyFilename);
|
||||||
ioc.UserName = i.GetStringExtra(KEY_SERVERUSERNAME) ?? "";
|
ioc.UserName = i.GetStringExtra(KeyServerusername) ?? "";
|
||||||
ioc.Password = i.GetStringExtra(KEY_SERVERPASSWORD) ?? "";
|
ioc.Password = i.GetStringExtra(KeyServerpassword) ?? "";
|
||||||
ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KEY_SERVERCREDMODE, (int) IOCredSaveMode.NoSave);
|
ioc.CredSaveMode = (IOCredSaveMode)i.GetIntExtra(KeyServercredmode, (int) IOCredSaveMode.NoSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Launch(Activity act, String fileName, AppTask appTask) {
|
public static void Launch(Activity act, String fileName, AppTask appTask) {
|
||||||
Java.IO.File dbFile = new Java.IO.File(fileName);
|
File dbFile = new File(fileName);
|
||||||
if ( ! dbFile.Exists() ) {
|
if ( ! dbFile.Exists() ) {
|
||||||
throw new Java.IO.FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Intent i = new Intent(act, typeof(PasswordActivity));
|
Intent i = new Intent(act, typeof(PasswordActivity));
|
||||||
i.PutExtra(KEY_FILENAME, fileName);
|
i.PutExtra(KeyFilename, fileName);
|
||||||
appTask.ToIntent(i);
|
appTask.ToIntent(i);
|
||||||
act.StartActivityForResult(i, 0);
|
act.StartActivityForResult(i, 0);
|
||||||
|
|
||||||
@ -128,52 +122,52 @@ namespace keepass2android
|
|||||||
|
|
||||||
public void LaunchNextActivity()
|
public void LaunchNextActivity()
|
||||||
{
|
{
|
||||||
mAppTask.AfterUnlockDatabase(this);
|
AppTask.AfterUnlockDatabase(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unloadDatabase()
|
void UnloadDatabase()
|
||||||
{
|
{
|
||||||
App.getDB().Clear();
|
App.Kp2a.GetDb().Clear();
|
||||||
StopService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
StopService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lockDatabase()
|
void LockDatabase()
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_LOCK);
|
SetResult(KeePass.ExitLock);
|
||||||
setEditText(Resource.Id.password, "");
|
SetEditText(Resource.Id.password, "");
|
||||||
if (App.getDB().QuickUnlockEnabled)
|
if (App.Kp2a.GetDb().QuickUnlockEnabled)
|
||||||
App.getDB().Locked = true;
|
App.Kp2a.GetDb().Locked = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unloadDatabase();
|
UnloadDatabase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lockAndClose()
|
void LockAndClose()
|
||||||
{
|
{
|
||||||
lockDatabase();
|
LockDatabase();
|
||||||
Finish();
|
Finish();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryStartQuickUnlock()
|
bool TryStartQuickUnlock()
|
||||||
{
|
{
|
||||||
if (!App.getDB().QuickUnlockEnabled)
|
if (!App.Kp2a.GetDb().QuickUnlockEnabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpPassword)) == false)
|
if (App.Kp2a.GetDb().KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)) == false)
|
||||||
return false;
|
return false;
|
||||||
KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword));
|
KcpPassword kcpPassword = (KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword));
|
||||||
String password = kcpPassword.Password.ReadString();
|
String password = kcpPassword.Password.ReadString();
|
||||||
|
|
||||||
if (password.Length == 0)
|
if (password.Length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
App.getDB().Locked = true;
|
App.Kp2a.GetDb().Locked = true;
|
||||||
|
|
||||||
Intent i = new Intent(this, typeof(QuickUnlock));
|
Intent i = new Intent(this, typeof(QuickUnlock));
|
||||||
PutIoConnectionToIntent(mIoConnection, i);
|
PutIoConnectionToIntent(_ioConnection, i);
|
||||||
Android.Util.Log.Debug("DEBUG","Starting QuickUnlock");
|
Android.Util.Log.Debug("DEBUG","Starting QuickUnlock");
|
||||||
StartActivityForResult(i,0);
|
StartActivityForResult(i,0);
|
||||||
return true;
|
return true;
|
||||||
@ -181,22 +175,22 @@ namespace keepass2android
|
|||||||
|
|
||||||
public void StartQuickUnlockForegroundService()
|
public void StartQuickUnlockForegroundService()
|
||||||
{
|
{
|
||||||
if (App.getDB().QuickUnlockEnabled)
|
if (App.Kp2a.GetDb().QuickUnlockEnabled)
|
||||||
{
|
{
|
||||||
StartService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
StartService(new Intent(this, typeof(QuickUnlockForegroundService)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startedWithActivityResult = false;
|
bool _startedWithActivityResult;
|
||||||
|
|
||||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||||
{
|
{
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
startedWithActivityResult = true;
|
_startedWithActivityResult = true;
|
||||||
Android.Util.Log.Debug("DEBUG","PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode);
|
Android.Util.Log.Debug("DEBUG","PasswordActivity.OnActivityResult "+resultCode+"/"+requestCode);
|
||||||
|
|
||||||
if (resultCode != KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE)
|
if (resultCode != KeePass.ExitCloseAfterTaskComplete)
|
||||||
{
|
{
|
||||||
//Stop service when app activity is left
|
//Stop service when app activity is left
|
||||||
StopService(new Intent(this, typeof(CopyToClipboardService)));
|
StopService(new Intent(this, typeof(CopyToClipboardService)));
|
||||||
@ -205,64 +199,63 @@ namespace keepass2android
|
|||||||
//NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works)
|
//NOTE: original code from k eepassdroid used switch ((Android.App.Result)requestCode) { (but doesn't work here, although k eepassdroid works)
|
||||||
switch(resultCode) {
|
switch(resultCode) {
|
||||||
|
|
||||||
case KeePass.EXIT_NORMAL:
|
case KeePass.ExitNormal:
|
||||||
if (!tryStartQuickUnlock())
|
if (!TryStartQuickUnlock())
|
||||||
{
|
{
|
||||||
setEditText(Resource.Id.password, "");
|
SetEditText(Resource.Id.password, "");
|
||||||
;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeePass.EXIT_LOCK:
|
case KeePass.ExitLock:
|
||||||
if (!tryStartQuickUnlock())
|
if (!TryStartQuickUnlock())
|
||||||
{
|
{
|
||||||
lockAndClose();
|
LockAndClose();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_FORCE_LOCK:
|
case KeePass.ExitForceLock:
|
||||||
setEditText(Resource.Id.password, "");
|
SetEditText(Resource.Id.password, "");
|
||||||
unloadDatabase();
|
UnloadDatabase();
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB:
|
case KeePass.ExitForceLockAndChangeDb:
|
||||||
unloadDatabase();
|
UnloadDatabase();
|
||||||
Finish();
|
Finish();
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_CHANGE_DB:
|
case KeePass.ExitChangeDb:
|
||||||
lockAndClose();
|
LockAndClose();
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE:
|
case KeePass.ExitCloseAfterTaskComplete:
|
||||||
SetResult(KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE);
|
SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||||
Finish();
|
Finish();
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_QUICK_UNLOCK:
|
case KeePass.ExitQuickUnlock:
|
||||||
App.getDB().Locked = false;
|
App.Kp2a.GetDb().Locked = false;
|
||||||
LaunchNextActivity();
|
LaunchNextActivity();
|
||||||
break;
|
break;
|
||||||
case KeePass.EXIT_RELOAD_DB:
|
case KeePass.ExitReloadDb:
|
||||||
//if the activity was killed, fill password/keyfile so the user can directly hit load again
|
//if the activity was killed, fill password/keyfile so the user can directly hit load again
|
||||||
if (App.getDB().Loaded)
|
if (App.Kp2a.GetDb().Loaded)
|
||||||
{
|
{
|
||||||
if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpPassword)))
|
if (App.Kp2a.GetDb().KpDatabase.MasterKey.ContainsType(typeof(KcpPassword)))
|
||||||
{
|
{
|
||||||
|
|
||||||
KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword));
|
KcpPassword kcpPassword = (KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword));
|
||||||
String password = kcpPassword.Password.ReadString();
|
String password = kcpPassword.Password.ReadString();
|
||||||
|
|
||||||
setEditText(Resource.Id.password, password);
|
SetEditText(Resource.Id.password, password);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpKeyFile)))
|
if (App.Kp2a.GetDb().KpDatabase.MasterKey.ContainsType(typeof(KcpKeyFile)))
|
||||||
{
|
{
|
||||||
|
|
||||||
KcpKeyFile kcpKeyfile = (KcpKeyFile)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpKeyFile));
|
KcpKeyFile kcpKeyfile = (KcpKeyFile)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpKeyFile));
|
||||||
|
|
||||||
setEditText(Resource.Id.pass_keyfile, kcpKeyfile.Path);
|
SetEditText(Resource.Id.pass_keyfile, kcpKeyfile.Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unloadDatabase();
|
UnloadDatabase();
|
||||||
break;
|
break;
|
||||||
case Android.App.Result.Ok:
|
case Result.Ok:
|
||||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_KEYFILE) {
|
if (requestCode == Intents.RequestCodeFileBrowseForKeyfile) {
|
||||||
string filename = Util.IntentToFilename(data);
|
string filename = Util.IntentToFilename(data);
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
if (filename.StartsWith("file://")) {
|
if (filename.StartsWith("file://")) {
|
||||||
@ -280,7 +273,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal AppTask mAppTask;
|
internal AppTask AppTask;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
@ -289,17 +282,17 @@ namespace keepass2android
|
|||||||
Intent i = Intent;
|
Intent i = Intent;
|
||||||
String action = i.Action;
|
String action = i.Action;
|
||||||
|
|
||||||
prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
_prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
mRememberKeyfile = prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
_rememberKeyfile = _prefs.GetBoolean(GetString(Resource.String.keyfile_key), Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
||||||
|
|
||||||
mIoConnection = new IOConnectionInfo();
|
_ioConnection = new IOConnectionInfo();
|
||||||
|
|
||||||
|
|
||||||
if (action != null && action.Equals(VIEW_INTENT))
|
if (action != null && action.Equals(ViewIntent))
|
||||||
{
|
{
|
||||||
mIoConnection.Path = i.DataString;
|
_ioConnection.Path = i.DataString;
|
||||||
|
|
||||||
if (! mIoConnection.Path.Substring(0, 7).Equals("file://"))
|
if (! _ioConnection.Path.Substring(0, 7).Equals("file://"))
|
||||||
{
|
{
|
||||||
//TODO: this might no longer be required as we can handle http(s) and ftp as well (but we need server credentials therefore)
|
//TODO: this might no longer be required as we can handle http(s) and ftp as well (but we need server credentials therefore)
|
||||||
Toast.MakeText(this, Resource.String.error_can_not_handle_uri, ToastLength.Long).Show();
|
Toast.MakeText(this, Resource.String.error_can_not_handle_uri, ToastLength.Long).Show();
|
||||||
@ -307,9 +300,9 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIoConnection.Path = URLDecoder.Decode(mIoConnection.Path.Substring(7));
|
_ioConnection.Path = URLDecoder.Decode(_ioConnection.Path.Substring(7));
|
||||||
|
|
||||||
if (mIoConnection.Path.Length == 0)
|
if (_ioConnection.Path.Length == 0)
|
||||||
{
|
{
|
||||||
// No file name
|
// No file name
|
||||||
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
||||||
@ -317,7 +310,7 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File dbFile = new File(mIoConnection.Path);
|
File dbFile = new File(_ioConnection.Path);
|
||||||
if (! dbFile.Exists())
|
if (! dbFile.Exists())
|
||||||
{
|
{
|
||||||
// File does not exist
|
// File does not exist
|
||||||
@ -326,22 +319,22 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mKeyFile = getKeyFile(mIoConnection.Path);
|
_keyFile = GetKeyFile(_ioConnection.Path);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
SetIoConnectionFromIntent(mIoConnection, i);
|
SetIoConnectionFromIntent(_ioConnection, i);
|
||||||
mKeyFile = i.GetStringExtra(KEY_KEYFILE);
|
_keyFile = i.GetStringExtra(KeyKeyfile);
|
||||||
if (mKeyFile == null || mKeyFile.Length == 0)
|
if (string.IsNullOrEmpty(_keyFile))
|
||||||
{
|
{
|
||||||
mKeyFile = getKeyFile(mIoConnection.Path);
|
_keyFile = GetKeyFile(_ioConnection.Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mAppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
AppTask = AppTask.GetTaskInOnCreate(savedInstanceState, Intent);
|
||||||
|
|
||||||
SetContentView(Resource.Layout.password);
|
SetContentView(Resource.Layout.password);
|
||||||
populateView();
|
PopulateView();
|
||||||
|
|
||||||
EditText passwordEdit = FindViewById<EditText>(Resource.Id.password);
|
EditText passwordEdit = FindViewById<EditText>(Resource.Id.password);
|
||||||
|
|
||||||
@ -350,33 +343,30 @@ namespace keepass2android
|
|||||||
Window.SetSoftInputMode(SoftInput.StateVisible);
|
Window.SetSoftInputMode(SoftInput.StateVisible);
|
||||||
|
|
||||||
Button confirmButton = (Button)FindViewById(Resource.Id.pass_ok);
|
Button confirmButton = (Button)FindViewById(Resource.Id.pass_ok);
|
||||||
confirmButton.Click += (object sender, EventArgs e) =>
|
confirmButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
String pass = GetEditText(Resource.Id.password);
|
String pass = GetEditText(Resource.Id.password);
|
||||||
String key = GetEditText(Resource.Id.pass_keyfile);
|
String key = GetEditText(Resource.Id.pass_keyfile);
|
||||||
if (pass.Length == 0 && key.Length == 0)
|
if (pass.Length == 0 && key.Length == 0)
|
||||||
{
|
{
|
||||||
errorMessage(Resource.String.error_nopass);
|
ErrorMessage(Resource.String.error_nopass);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileName = GetEditText(Resource.Id.filename);
|
|
||||||
|
|
||||||
|
|
||||||
// Clear before we load
|
// Clear before we load
|
||||||
unloadDatabase();
|
UnloadDatabase();
|
||||||
|
|
||||||
// Clear the shutdown flag
|
// Clear the shutdown flag
|
||||||
App.clearShutdown();
|
App.Kp2a.ClearShutdown();
|
||||||
|
|
||||||
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
||||||
App.getDB().QuickUnlockEnabled = cbQuickUnlock.Checked;
|
App.Kp2a.GetDb().QuickUnlockEnabled = cbQuickUnlock.Checked;
|
||||||
App.getDB().QuickUnlockKeyLength = int.Parse(prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default)));
|
App.Kp2a.GetDb().QuickUnlockKeyLength = int.Parse(_prefs.GetString(GetString(Resource.String.QuickUnlockLength_key), GetString(Resource.String.QuickUnlockLength_default)));
|
||||||
|
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
LoadDB task = new LoadDB(App.getDB(), this, mIoConnection, pass, key, new AfterLoad(handler, this));
|
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, pass, key, new AfterLoad(handler, this));
|
||||||
ProgressTask pt = new ProgressTask(this, task, Resource.String.loading_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, this, task, UiStringKey.loading_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*CheckBox checkBox = (CheckBox) FindViewById(Resource.Id.show_password);
|
/*CheckBox checkBox = (CheckBox) FindViewById(Resource.Id.show_password);
|
||||||
@ -392,10 +382,10 @@ namespace keepass2android
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
|
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
|
||||||
btnTogglePassword.Click += (object sender, EventArgs e) => {
|
btnTogglePassword.Click += (sender, e) => {
|
||||||
mShowPassword = !mShowPassword;
|
_showPassword = !_showPassword;
|
||||||
TextView password = (TextView)FindViewById(Resource.Id.password);
|
TextView password = (TextView)FindViewById(Resource.Id.password);
|
||||||
if (mShowPassword)
|
if (_showPassword)
|
||||||
{
|
{
|
||||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||||
} else
|
} else
|
||||||
@ -405,49 +395,49 @@ namespace keepass2android
|
|||||||
};
|
};
|
||||||
|
|
||||||
CheckBox defaultCheck = (CheckBox)FindViewById(Resource.Id.default_database);
|
CheckBox defaultCheck = (CheckBox)FindViewById(Resource.Id.default_database);
|
||||||
///Don't allow the current file to be the default if we don't have stored credentials
|
//Don't allow the current file to be the default if we don't have stored credentials
|
||||||
if ((mIoConnection.IsLocalFile() == false) && (mIoConnection.CredSaveMode != IOCredSaveMode.SaveCred))
|
if ((_ioConnection.IsLocalFile() == false) && (_ioConnection.CredSaveMode != IOCredSaveMode.SaveCred))
|
||||||
{
|
{
|
||||||
defaultCheck.Enabled = false;
|
defaultCheck.Enabled = false;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
defaultCheck.Enabled = true;
|
defaultCheck.Enabled = true;
|
||||||
}
|
}
|
||||||
defaultCheck.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
|
defaultCheck.CheckedChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
String newDefaultFileName;
|
String newDefaultFileName;
|
||||||
|
|
||||||
if (e.IsChecked)
|
if (e.IsChecked)
|
||||||
{
|
{
|
||||||
newDefaultFileName = mIoConnection.Path;
|
newDefaultFileName = _ioConnection.Path;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
newDefaultFileName = "";
|
newDefaultFileName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
ISharedPreferencesEditor editor = prefs.Edit();
|
ISharedPreferencesEditor editor = _prefs.Edit();
|
||||||
editor.PutString(KEY_DEFAULT_FILENAME, newDefaultFileName);
|
editor.PutString(KeyDefaultFilename, newDefaultFileName);
|
||||||
EditorCompat.apply(editor);
|
EditorCompat.Apply(editor);
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageButton browse = (ImageButton)FindViewById(Resource.Id.browse_button);
|
ImageButton browse = (ImageButton)FindViewById(Resource.Id.browse_button);
|
||||||
browse.Click += (object sender, EventArgs evt) =>
|
browse.Click += (sender, evt) =>
|
||||||
{
|
{
|
||||||
string filename = null;
|
string filename = null;
|
||||||
if (!String.IsNullOrEmpty(mIoConnection.Path))
|
if (!String.IsNullOrEmpty(_ioConnection.Path))
|
||||||
{
|
{
|
||||||
File keyfile = new File(mIoConnection.Path);
|
File keyfile = new File(_ioConnection.Path);
|
||||||
File parent = keyfile.ParentFile;
|
File parent = keyfile.ParentFile;
|
||||||
if (parent != null)
|
if (parent != null)
|
||||||
{
|
{
|
||||||
filename = parent.AbsolutePath;
|
filename = parent.AbsolutePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Util.showBrowseDialog(filename, this, Intents.REQUEST_CODE_FILE_BROWSE_FOR_KEYFILE, false);
|
Util.showBrowseDialog(filename, this, Intents.RequestCodeFileBrowseForKeyfile, false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
retrieveSettings();
|
RetrieveSettings();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -455,7 +445,7 @@ namespace keepass2android
|
|||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
mAppTask.ToBundle(outState);
|
AppTask.ToBundle(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume() {
|
protected override void OnResume() {
|
||||||
@ -463,45 +453,45 @@ namespace keepass2android
|
|||||||
|
|
||||||
// If the application was shutdown make sure to clear the password field, if it
|
// If the application was shutdown make sure to clear the password field, if it
|
||||||
// was saved in the instance state
|
// was saved in the instance state
|
||||||
if (App.isShutdown()) {
|
if (App.Kp2a.IsShutdown()) {
|
||||||
lockDatabase();
|
LockDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the shutdown flag
|
// Clear the shutdown flag
|
||||||
App.clearShutdown();
|
App.Kp2a.ClearShutdown();
|
||||||
|
|
||||||
if (startedWithActivityResult)
|
if (_startedWithActivityResult)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (App.getDB().Loaded && (App.getDB().mIoc != null)
|
if (App.Kp2a.GetDb().Loaded && (App.Kp2a.GetDb().Ioc != null)
|
||||||
&& (mIoConnection != null) && (App.getDB().mIoc.GetDisplayName() == mIoConnection.GetDisplayName()))
|
&& (_ioConnection != null) && (App.Kp2a.GetDb().Ioc.GetDisplayName() == _ioConnection.GetDisplayName()))
|
||||||
{
|
{
|
||||||
if (App.getDB().Locked == false)
|
if (App.Kp2a.GetDb().Locked == false)
|
||||||
{
|
{
|
||||||
LaunchNextActivity();
|
LaunchNextActivity();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tryStartQuickUnlock();
|
TryStartQuickUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retrieveSettings() {
|
private void RetrieveSettings() {
|
||||||
String defaultFilename = prefs.GetString(KEY_DEFAULT_FILENAME, "");
|
String defaultFilename = _prefs.GetString(KeyDefaultFilename, "");
|
||||||
if (!String.IsNullOrEmpty(mIoConnection.Path) && mIoConnection.Path.Equals(defaultFilename)) {
|
if (!String.IsNullOrEmpty(_ioConnection.Path) && _ioConnection.Path.Equals(defaultFilename)) {
|
||||||
CheckBox checkbox = (CheckBox) FindViewById(Resource.Id.default_database);
|
CheckBox checkbox = (CheckBox) FindViewById(Resource.Id.default_database);
|
||||||
checkbox.Checked = true;
|
checkbox.Checked = true;
|
||||||
}
|
}
|
||||||
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
CheckBox cbQuickUnlock = (CheckBox)FindViewById(Resource.Id.enable_quickunlock);
|
||||||
cbQuickUnlock.Checked = prefs.GetBoolean(GetString(Resource.String.QuickUnlockDefaultEnabled_key), true);
|
cbQuickUnlock.Checked = _prefs.GetBoolean(GetString(Resource.String.QuickUnlockDefaultEnabled_key), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKeyFile(String filename) {
|
private String GetKeyFile(String filename) {
|
||||||
if ( mRememberKeyfile ) {
|
if ( _rememberKeyfile ) {
|
||||||
FileDbHelper dbHelp = App.fileDbHelper;
|
FileDbHelper dbHelp = App.Kp2a.FileDbHelper;
|
||||||
|
|
||||||
String keyfile = dbHelp.getFileByName(filename);
|
String keyfile = dbHelp.GetFileByName(filename);
|
||||||
|
|
||||||
return keyfile;
|
return keyfile;
|
||||||
} else {
|
} else {
|
||||||
@ -509,9 +499,9 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateView() {
|
private void PopulateView() {
|
||||||
setEditText(Resource.Id.filename, mIoConnection.GetDisplayName());
|
SetEditText(Resource.Id.filename, _ioConnection.GetDisplayName());
|
||||||
setEditText(Resource.Id.pass_keyfile, mKeyFile);
|
SetEditText(Resource.Id.pass_keyfile, _keyFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -521,7 +511,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private void errorMessage(int resId)
|
private void ErrorMessage(int resId)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, resId, ToastLength.Long).Show();
|
Toast.MakeText(this, resId, ToastLength.Long).Show();
|
||||||
}
|
}
|
||||||
@ -530,7 +520,7 @@ namespace keepass2android
|
|||||||
return Util.getEditText(this, resId);
|
return Util.getEditText(this, resId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEditText(int resId, String str) {
|
private void SetEditText(int resId, String str) {
|
||||||
TextView te = (TextView) FindViewById(resId);
|
TextView te = (TextView) FindViewById(resId);
|
||||||
//assert(te == null);
|
//assert(te == null);
|
||||||
|
|
||||||
@ -564,20 +554,18 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class AfterLoad : OnFinish {
|
private class AfterLoad : OnFinish {
|
||||||
|
readonly PasswordActivity _act;
|
||||||
|
|
||||||
PasswordActivity act;
|
|
||||||
public AfterLoad(Handler handler, PasswordActivity act):base(handler) {
|
public AfterLoad(Handler handler, PasswordActivity act):base(handler) {
|
||||||
this.act = act;
|
_act = act;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
act.StartQuickUnlockForegroundService();
|
_act.StartQuickUnlockForegroundService();
|
||||||
act.LaunchNextActivity();
|
_act.LaunchNextActivity();
|
||||||
} else {
|
} else {
|
||||||
displayMessage(act);
|
DisplayMessage(_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
@ -36,19 +30,19 @@ namespace keepass2android
|
|||||||
public class PwGroupListAdapter : BaseAdapter
|
public class PwGroupListAdapter : BaseAdapter
|
||||||
{
|
{
|
||||||
|
|
||||||
private GroupBaseActivity mAct;
|
private readonly GroupBaseActivity _act;
|
||||||
private PwGroup mGroup;
|
private readonly PwGroup _group;
|
||||||
private List<PwGroup> groupsForViewing;
|
private List<PwGroup> _groupsForViewing;
|
||||||
private List<PwEntry> entriesForViewing;
|
private List<PwEntry> _entriesForViewing;
|
||||||
|
|
||||||
private ISharedPreferences prefs;
|
private readonly ISharedPreferences _prefs;
|
||||||
|
|
||||||
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
||||||
mAct = act;
|
_act = act;
|
||||||
mGroup = group;
|
_group = group;
|
||||||
prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
_prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
||||||
|
|
||||||
filterAndSort();
|
FilterAndSort();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,41 +50,41 @@ namespace keepass2android
|
|||||||
public override void NotifyDataSetChanged() {
|
public override void NotifyDataSetChanged() {
|
||||||
base.NotifyDataSetChanged();
|
base.NotifyDataSetChanged();
|
||||||
|
|
||||||
filterAndSort();
|
FilterAndSort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void NotifyDataSetInvalidated() {
|
public override void NotifyDataSetInvalidated() {
|
||||||
base.NotifyDataSetInvalidated();
|
base.NotifyDataSetInvalidated();
|
||||||
|
|
||||||
filterAndSort();
|
FilterAndSort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void filterAndSort() {
|
private void FilterAndSort() {
|
||||||
entriesForViewing = new List<PwEntry>();
|
_entriesForViewing = new List<PwEntry>();
|
||||||
|
|
||||||
foreach (PwEntry entry in mGroup.Entries)
|
foreach (PwEntry entry in _group.Entries)
|
||||||
{
|
{
|
||||||
entriesForViewing.Add(entry);
|
_entriesForViewing.Add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sortLists = prefs.GetBoolean(mAct.GetString(Resource.String.sort_key), mAct.Resources.GetBoolean(Resource.Boolean.sort_default));
|
bool sortLists = _prefs.GetBoolean(_act.GetString(Resource.String.sort_key), _act.Resources.GetBoolean(Resource.Boolean.sort_default));
|
||||||
if ( sortLists )
|
if ( sortLists )
|
||||||
{
|
{
|
||||||
groupsForViewing = new List<PwGroup>(mGroup.Groups);
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
||||||
groupsForViewing.Sort( (PwGroup x,PwGroup y) => { return String.Compare (x.Name, y.Name, true); });
|
_groupsForViewing.Sort( (x, y) => { return String.Compare (x.Name, y.Name, true); });
|
||||||
entriesForViewing.Sort( (PwEntry x, PwEntry y) =>
|
_entriesForViewing.Sort( (x, y) =>
|
||||||
{
|
{
|
||||||
String nameX = x.Strings.ReadSafe(PwDefs.TitleField);
|
String nameX = x.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
String nameY = y.Strings.ReadSafe(PwDefs.TitleField);
|
String nameY = y.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
if (nameX.ToLower() != nameY.ToLower())
|
if (nameX.ToLower() != nameY.ToLower())
|
||||||
return String.Compare (nameX,nameY,true);
|
return String.Compare(nameX, nameY, StringComparison.OrdinalIgnoreCase);
|
||||||
else
|
else
|
||||||
return x.CreationTime.CompareTo(y.CreationTime);
|
return x.CreationTime.CompareTo(y.CreationTime);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
groupsForViewing = new List<PwGroup>(mGroup.Groups);
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +92,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
get{
|
get{
|
||||||
|
|
||||||
return groupsForViewing.Count + entriesForViewing.Count;
|
return _groupsForViewing.Count + _entriesForViewing.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,42 +105,42 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override View GetView(int position, View convertView, ViewGroup parent) {
|
public override View GetView(int position, View convertView, ViewGroup parent) {
|
||||||
int size = groupsForViewing.Count;
|
int size = _groupsForViewing.Count;
|
||||||
|
|
||||||
if ( position < size ) {
|
if ( position < size ) {
|
||||||
return createGroupView(position, convertView);
|
return CreateGroupView(position, convertView);
|
||||||
} else {
|
} else {
|
||||||
return createEntryView(position - size, convertView);
|
return CreateEntryView(position - size, convertView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private View createGroupView(int position, View convertView) {
|
private View CreateGroupView(int position, View convertView) {
|
||||||
PwGroup g = groupsForViewing[position];
|
PwGroup g = _groupsForViewing[position];
|
||||||
PwGroupView gv;
|
PwGroupView gv;
|
||||||
|
|
||||||
if (convertView == null || !(convertView is PwGroupView)) {
|
if (convertView == null || !(convertView is PwGroupView)) {
|
||||||
|
|
||||||
gv = PwGroupView.getInstance(mAct, g);
|
gv = PwGroupView.GetInstance(_act, g);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gv = (PwGroupView) convertView;
|
gv = (PwGroupView) convertView;
|
||||||
gv.convertView(g);
|
gv.ConvertView(g);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return gv;
|
return gv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PwEntryView createEntryView(int position, View convertView) {
|
private PwEntryView CreateEntryView(int position, View convertView) {
|
||||||
PwEntry entry = entriesForViewing[position];
|
PwEntry entry = _entriesForViewing[position];
|
||||||
PwEntryView ev;
|
PwEntryView ev;
|
||||||
|
|
||||||
if (convertView == null || !(convertView is PwEntryView)) {
|
if (convertView == null || !(convertView is PwEntryView)) {
|
||||||
ev = PwEntryView.getInstance(mAct, entry, position);
|
ev = PwEntryView.GetInstance(_act, entry, position);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ev = (PwEntryView) convertView;
|
ev = (PwEntryView) convertView;
|
||||||
ev.convertView(entry, position);
|
ev.ConvertView(entry, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
|
@ -16,14 +16,9 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
@ -37,16 +32,15 @@ namespace keepass2android
|
|||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")]
|
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/Base")]
|
||||||
public class QuickUnlock : LifecycleDebugActivity
|
public class QuickUnlock : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
IOConnectionInfo mIoc;
|
IOConnectionInfo _ioc;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle bundle)
|
protected override void OnCreate(Bundle bundle)
|
||||||
{
|
{
|
||||||
base.OnCreate(bundle);
|
base.OnCreate(bundle);
|
||||||
|
|
||||||
Intent i = Intent;
|
_ioc = App.Kp2a.GetDb().Ioc;
|
||||||
mIoc = App.getDB().mIoc;
|
|
||||||
|
|
||||||
if (mIoc == null)
|
if (_ioc == null)
|
||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
return;
|
return;
|
||||||
@ -55,20 +49,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
SetContentView(Resource.Layout.QuickUnlock);
|
SetContentView(Resource.Layout.QuickUnlock);
|
||||||
|
|
||||||
if (App.getDB().pm.Name != "")
|
if (App.Kp2a.GetDb().KpDatabase.Name != "")
|
||||||
{
|
{
|
||||||
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Invisible;
|
FindViewById(Resource.Id.filename_label).Visibility = ViewStates.Invisible;
|
||||||
((TextView)FindViewById(Resource.Id.qu_filename)).Text = App.getDB().pm.Name;
|
((TextView)FindViewById(Resource.Id.qu_filename)).Text = App.Kp2a.GetDb().KpDatabase.Name;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
((TextView)FindViewById(Resource.Id.qu_filename)).Text = mIoc.Path;
|
((TextView)FindViewById(Resource.Id.qu_filename)).Text = _ioc.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextView txtLabel = (TextView)FindViewById(Resource.Id.QuickUnlock_label);
|
TextView txtLabel = (TextView)FindViewById(Resource.Id.QuickUnlock_label);
|
||||||
|
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
int quickUnlockLength = App.Kp2a.GetDb().QuickUnlockKeyLength;
|
||||||
int quickUnlockLength = App.getDB().QuickUnlockKeyLength;
|
|
||||||
|
|
||||||
txtLabel.Text = GetString(Resource.String.QuickUnlock_label, new Java.Lang.Object[]{quickUnlockLength});
|
txtLabel.Text = GetString(Resource.String.QuickUnlock_label, new Java.Lang.Object[]{quickUnlockLength});
|
||||||
|
|
||||||
@ -79,21 +72,21 @@ namespace keepass2android
|
|||||||
keyboard.ShowSoftInput(pwd, 0);
|
keyboard.ShowSoftInput(pwd, 0);
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
SetResult(KeePass.EXIT_CHANGE_DB);
|
SetResult(KeePass.ExitChangeDb);
|
||||||
|
|
||||||
Button btnUnlock = (Button)FindViewById(Resource.Id.QuickUnlock_button);
|
Button btnUnlock = (Button)FindViewById(Resource.Id.QuickUnlock_button);
|
||||||
btnUnlock.Click += (object sender, EventArgs e) =>
|
btnUnlock.Click += (object sender, EventArgs e) =>
|
||||||
{
|
{
|
||||||
KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword));
|
KcpPassword kcpPassword = (KcpPassword)App.Kp2a.GetDb().KpDatabase.MasterKey.GetUserKey(typeof(KcpPassword));
|
||||||
String password = kcpPassword.Password.ReadString();
|
String password = kcpPassword.Password.ReadString();
|
||||||
String expectedPasswordPart = password.Substring(Math.Max(0,password.Length-quickUnlockLength),Math.Min(password.Length, quickUnlockLength));
|
String expectedPasswordPart = password.Substring(Math.Max(0,password.Length-quickUnlockLength),Math.Min(password.Length, quickUnlockLength));
|
||||||
if (pwd.Text == expectedPasswordPart)
|
if (pwd.Text == expectedPasswordPart)
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_QUICK_UNLOCK);
|
SetResult(KeePass.ExitQuickUnlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_FORCE_LOCK);
|
SetResult(KeePass.ExitForceLock);
|
||||||
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
||||||
}
|
}
|
||||||
Finish();
|
Finish();
|
||||||
@ -102,7 +95,7 @@ namespace keepass2android
|
|||||||
Button btnLock = (Button)FindViewById(Resource.Id.QuickUnlock_buttonLock);
|
Button btnLock = (Button)FindViewById(Resource.Id.QuickUnlock_buttonLock);
|
||||||
btnLock.Click += (object sender, EventArgs e) =>
|
btnLock.Click += (object sender, EventArgs e) =>
|
||||||
{
|
{
|
||||||
SetResult(KeePass.EXIT_FORCE_LOCK_AND_CHANGE_DB);
|
SetResult(KeePass.ExitForceLockAndChangeDb);
|
||||||
Finish();
|
Finish();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -112,8 +105,8 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
|
|
||||||
if ( ! App.getDB().Loaded ) {
|
if ( ! App.Kp2a.GetDb().Loaded ) {
|
||||||
SetResult(KeePass.EXIT_CHANGE_DB);
|
SetResult(KeePass.ExitChangeDb);
|
||||||
Finish();
|
Finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
1342
src/keepass2android/Resources/Resource.designer.cs
generated
1342
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -15,15 +15,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -32,22 +25,18 @@ namespace keepass2android
|
|||||||
public class SetPasswordDialog : CancelDialog
|
public class SetPasswordDialog : CancelDialog
|
||||||
{
|
{
|
||||||
|
|
||||||
internal String mKeyfile;
|
internal String Keyfile;
|
||||||
private FileOnFinish mFinish;
|
private readonly FileOnFinish _finish;
|
||||||
|
|
||||||
public SetPasswordDialog(Context context):base(context) {
|
public SetPasswordDialog(Context context):base(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetPasswordDialog(Context context, FileOnFinish finish):base(context) {
|
public SetPasswordDialog(Context context, FileOnFinish finish):base(context) {
|
||||||
|
|
||||||
mFinish = finish;
|
_finish = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String keyfile() {
|
|
||||||
return mKeyfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
@ -57,7 +46,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
// Ok button
|
// Ok button
|
||||||
Button okButton = (Button) FindViewById(Resource.Id.ok);
|
Button okButton = (Button) FindViewById(Resource.Id.ok);
|
||||||
okButton.Click += (object sender, EventArgs e) =>
|
okButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
TextView passView = (TextView) FindViewById(Resource.Id.pass_password);
|
TextView passView = (TextView) FindViewById(Resource.Id.pass_password);
|
||||||
String pass = passView.Text;
|
String pass = passView.Text;
|
||||||
@ -73,7 +62,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
TextView keyfileView = (TextView) FindViewById(Resource.Id.pass_keyfile);
|
TextView keyfileView = (TextView) FindViewById(Resource.Id.pass_keyfile);
|
||||||
String keyfile = keyfileView.Text;
|
String keyfile = keyfileView.Text;
|
||||||
mKeyfile = keyfile;
|
Keyfile = keyfile;
|
||||||
|
|
||||||
// Verify that a password or keyfile is set
|
// Verify that a password or keyfile is set
|
||||||
if ( pass.Length == 0 && keyfile.Length == 0 ) {
|
if ( pass.Length == 0 && keyfile.Length == 0 ) {
|
||||||
@ -82,9 +71,9 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPassword sp = new SetPassword(Context, App.getDB(), pass, keyfile, new AfterSave(this, mFinish, new Handler()));
|
SetPassword sp = new SetPassword(Context, App.Kp2a.GetDb(), pass, keyfile, new AfterSave(this, _finish, new Handler()));
|
||||||
ProgressTask pt = new ProgressTask(Context, sp, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, Context, sp, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -93,8 +82,8 @@ namespace keepass2android
|
|||||||
Button cancelButton = (Button) FindViewById(Resource.Id.cancel);
|
Button cancelButton = (Button) FindViewById(Resource.Id.cancel);
|
||||||
cancelButton.Click += (sender,e) => {
|
cancelButton.Click += (sender,e) => {
|
||||||
Cancel();
|
Cancel();
|
||||||
if ( mFinish != null ) {
|
if ( _finish != null ) {
|
||||||
mFinish.run();
|
_finish.Run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -102,28 +91,28 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
class AfterSave : OnFinish {
|
class AfterSave : OnFinish {
|
||||||
private FileOnFinish mFinish;
|
private readonly FileOnFinish _finish;
|
||||||
|
|
||||||
SetPasswordDialog dlg;
|
readonly SetPasswordDialog _dlg;
|
||||||
|
|
||||||
public AfterSave(SetPasswordDialog dlg, FileOnFinish finish, Handler handler): base(finish, handler) {
|
public AfterSave(SetPasswordDialog dlg, FileOnFinish finish, Handler handler): base(finish, handler) {
|
||||||
mFinish = finish;
|
_finish = finish;
|
||||||
this.dlg = dlg;
|
_dlg = dlg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
if ( mFinish != null ) {
|
if ( _finish != null ) {
|
||||||
mFinish.setFilename(dlg.mKeyfile);
|
_finish.Filename = _dlg.Keyfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.Dismiss();
|
_dlg.Dismiss();
|
||||||
} else {
|
} else {
|
||||||
displayMessage(dlg.Context);
|
DisplayMessage(_dlg.Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,13 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using keepass2android.view;
|
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -54,35 +50,35 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Database mDb;
|
private Database _db;
|
||||||
|
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
SetResult(KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE);
|
SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||||
|
|
||||||
mDb = App.getDB();
|
_db = App.Kp2a.GetDb();
|
||||||
|
|
||||||
String searchUrl = ((SearchUrlTask)mAppTask).UrlToSearchFor;
|
String searchUrl = ((SearchUrlTask)AppTask).UrlToSearchFor;
|
||||||
|
|
||||||
if (!mDb.Loaded)
|
if (!_db.Loaded)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
Intent intent = new Intent(this, typeof(FileSelectActivity));
|
||||||
mAppTask.ToIntent(intent);
|
AppTask.ToIntent(intent);
|
||||||
StartActivityForResult(intent, 0);
|
StartActivityForResult(intent, 0);
|
||||||
|
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
else if (mDb.Locked)
|
else if (_db.Locked)
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this,mDb.mIoc, mAppTask);
|
PasswordActivity.Launch(this,_db.Ioc, AppTask);
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query(searchUrl);
|
Query(searchUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -90,7 +86,7 @@ namespace keepass2android
|
|||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
mAppTask.ToBundle(outState);
|
AppTask.ToBundle(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LaunchActivityForEntry(KeePassLib.PwEntry pwEntry, int pos)
|
public override void LaunchActivityForEntry(KeePassLib.PwEntry pwEntry, int pos)
|
||||||
@ -99,12 +95,12 @@ namespace keepass2android
|
|||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void query(String url)
|
private void Query(String url)
|
||||||
{
|
{
|
||||||
//first: search for exact url
|
//first: search for exact url
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mGroup = mDb.SearchForExactUrl(url);
|
Group = _db.SearchForExactUrl(url);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||||
@ -112,11 +108,11 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if no results, search for host (e.g. "accounts.google.com")
|
//if no results, search for host (e.g. "accounts.google.com")
|
||||||
if (mGroup.Entries.Count() == 0)
|
if (!Group.Entries.Any())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mGroup = mDb.SearchForHost(url, false);
|
Group = _db.SearchForHost(url, false);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||||
@ -125,11 +121,11 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//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 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 (mGroup.Entries.Count() == 0)
|
if (!Group.Entries.Any())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mGroup = mDb.SearchForHost(url, true);
|
Group = _db.SearchForHost(url, true);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||||
@ -138,14 +134,14 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if there is exactly one match: open the entry
|
//if there is exactly one match: open the entry
|
||||||
if (mGroup.Entries.Count() == 1)
|
if (Group.Entries.Count() == 1)
|
||||||
{
|
{
|
||||||
LaunchActivityForEntry(mGroup.Entries.Single(),0);
|
LaunchActivityForEntry(Group.Entries.Single(),0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//show results:
|
//show results:
|
||||||
if (mGroup == null || (mGroup.Entries.Count() < 1))
|
if (Group == null || (!Group.Entries.Any()))
|
||||||
{
|
{
|
||||||
//SetContentView(new GroupEmptyView(this));
|
//SetContentView(new GroupEmptyView(this));
|
||||||
SetContentView(Resource.Layout.searchurlresults_empty);
|
SetContentView(Resource.Layout.searchurlresults_empty);
|
||||||
@ -155,29 +151,23 @@ namespace keepass2android
|
|||||||
//SetContentView(new GroupViewOnlyView(this));
|
//SetContentView(new GroupViewOnlyView(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
setGroupTitle();
|
SetGroupTitle();
|
||||||
|
|
||||||
ListAdapter = new PwGroupListAdapter(this, mGroup);
|
ListAdapter = new PwGroupListAdapter(this, Group);
|
||||||
|
|
||||||
View selectOtherEntry = FindViewById (Resource.Id.select_other_entry);
|
View selectOtherEntry = FindViewById (Resource.Id.select_other_entry);
|
||||||
selectOtherEntry.Click += (object sender, EventArgs e) => {
|
selectOtherEntry.Click += (sender, e) => {
|
||||||
GroupActivity.Launch (this, new SelectEntryTask());
|
GroupActivity.Launch (this, new SelectEntryTask());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
View createUrlEntry = FindViewById (Resource.Id.add_url_entry);
|
View createUrlEntry = FindViewById (Resource.Id.add_url_entry);
|
||||||
createUrlEntry.Click += (object sender, EventArgs e) => {
|
createUrlEntry.Click += (sender, e) => {
|
||||||
GroupActivity.Launch (this, new CreateEntryThenCloseTask() { Url = url } );
|
GroupActivity.Launch (this, new CreateEntryThenCloseTask { Url = url } );
|
||||||
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[]{GetString(Resource.String.add_entry)}), ToastLength.Long ).Show();
|
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[]{GetString(Resource.String.add_entry)}), ToastLength.Long ).Show();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getSearchUrl(Intent queryIntent) {
|
|
||||||
String queryAction = queryIntent.Action;
|
|
||||||
return queryIntent.GetStringExtra(Intent.ExtraText);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnSearchRequested()
|
public override bool OnSearchRequested()
|
||||||
|
@ -21,20 +21,14 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
using KeePass.Util.Spr;
|
using KeePass.Util.Spr;
|
||||||
|
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using KeePassLib.Collections;
|
using KeePassLib.Collections;
|
||||||
using KeePassLib.Cryptography;
|
using KeePassLib.Cryptography;
|
||||||
using KeePassLib.Cryptography.PasswordGenerator;
|
|
||||||
using KeePassLib.Delegates;
|
using KeePassLib.Delegates;
|
||||||
using KeePassLib.Security;
|
using KeePassLib.Security;
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
using KeePassLib.Serialization;
|
|
||||||
|
|
||||||
namespace KeePass.Util
|
namespace KeePass.Util
|
||||||
{
|
{
|
||||||
@ -46,7 +40,6 @@ namespace KeePass.Util
|
|||||||
|
|
||||||
// Old format name (<= 2.14): "KeePassEntriesCF"
|
// Old format name (<= 2.14): "KeePassEntriesCF"
|
||||||
public const string ClipFormatEntries = "KeePassEntriesCX";
|
public const string ClipFormatEntries = "KeePassEntriesCX";
|
||||||
private static byte[] AdditionalEntropy = { 0xF8, 0x03, 0xFA, 0x51, 0x87, 0x18, 0x49, 0x5D };
|
|
||||||
|
|
||||||
public static string FillPlaceholders(string strText, SprContext ctx)
|
public static string FillPlaceholders(string strText, SprContext ctx)
|
||||||
{
|
{
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 Android.Content.PM;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
|
|
||||||
public class Interaction {
|
|
||||||
/**
|
|
||||||
* Indicates whether the specified action can be used as an intent. This
|
|
||||||
* method queries the package manager for installed packages that can
|
|
||||||
* respond to an intent with the specified action. If no suitable package is
|
|
||||||
* found, this method returns false.
|
|
||||||
*
|
|
||||||
* @param context The application's environment.
|
|
||||||
* @param action The Intent action to check for availability.
|
|
||||||
*
|
|
||||||
* @return True if an Intent with the specified action can be sent and
|
|
||||||
* responded to, false otherwise.
|
|
||||||
*/
|
|
||||||
public static bool isIntentAvailable(Context context, String action, String type) {
|
|
||||||
PackageManager packageManager = context.PackageManager;
|
|
||||||
Intent intent = new Intent(action);
|
|
||||||
if (type != null)
|
|
||||||
intent.SetType(type);
|
|
||||||
IList<ResolveInfo> list =
|
|
||||||
packageManager.QueryIntentActivities(intent,
|
|
||||||
PackageInfoFlags.MatchDefaultOnly);
|
|
||||||
foreach (ResolveInfo i in list)
|
|
||||||
Android.Util.Log.Debug("DEBUG", i.ActivityInfo.ApplicationInfo.PackageName);
|
|
||||||
return list.Count > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -597,7 +597,7 @@ namespace KeePass.Util.Spr
|
|||||||
if(!MightDeref(str)) return str;
|
if(!MightDeref(str)) return str;
|
||||||
|
|
||||||
SprContext ctx = new SprContext(pe,
|
SprContext ctx = new SprContext(pe,
|
||||||
App.getDB().pm,
|
App.Kp2a.GetDb().KpDatabase,
|
||||||
SprCompileFlags.Deref);
|
SprCompileFlags.Deref);
|
||||||
// ctx.ForcePlainTextPasswords = false;
|
// ctx.ForcePlainTextPasswords = false;
|
||||||
|
|
||||||
|
@ -101,20 +101,45 @@ namespace keepass2android
|
|||||||
te.Text = str;
|
te.Text = str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the specified action can be used as an intent. This
|
||||||
|
* method queries the package manager for installed packages that can
|
||||||
|
* respond to an intent with the specified action. If no suitable package is
|
||||||
|
* found, this method returns false.
|
||||||
|
*
|
||||||
|
* @param context The application's environment.
|
||||||
|
* @param action The Intent action to check for availability.
|
||||||
|
*
|
||||||
|
* @return True if an Intent with the specified action can be sent and
|
||||||
|
* responded to, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool IsIntentAvailable(Context context, String action, String type)
|
||||||
|
{
|
||||||
|
PackageManager packageManager = context.PackageManager;
|
||||||
|
Intent intent = new Intent(action);
|
||||||
|
if (type != null)
|
||||||
|
intent.SetType(type);
|
||||||
|
IList<ResolveInfo> list =
|
||||||
|
packageManager.QueryIntentActivities(intent,
|
||||||
|
PackageInfoFlags.MatchDefaultOnly);
|
||||||
|
foreach (ResolveInfo i in list)
|
||||||
|
Android.Util.Log.Debug("DEBUG", i.ActivityInfo.ApplicationInfo.PackageName);
|
||||||
|
return list.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static void showBrowseDialog(string filename, Activity act, int requestCodeBrowse, bool forSaving)
|
public static void showBrowseDialog(string filename, Activity act, int requestCodeBrowse, bool forSaving)
|
||||||
{
|
{
|
||||||
if ((!forSaving) && (Interaction.isIntentAvailable(act, Intent.ActionGetContent, "file/*"))) {
|
if ((!forSaving) && (IsIntentAvailable(act, Intent.ActionGetContent, "file/*"))) {
|
||||||
Intent i = new Intent(Intent.ActionGetContent);
|
Intent i = new Intent(Intent.ActionGetContent);
|
||||||
i.SetType("file/*");
|
i.SetType("file/*");
|
||||||
|
|
||||||
act.StartActivityForResult(i, requestCodeBrowse);
|
act.StartActivityForResult(i, requestCodeBrowse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Interaction.isIntentAvailable(act, Intents.FILE_BROWSE, null))
|
if (IsIntentAvailable(act, Intents.FileBrowse, null))
|
||||||
{
|
{
|
||||||
Intent i = new Intent(Intents.FILE_BROWSE);
|
Intent i = new Intent(Intents.FileBrowse);
|
||||||
if (filename != null)
|
if (filename != null)
|
||||||
i.SetData(Android.Net.Uri.Parse("file://" + filename));
|
i.SetData(Android.Net.Uri.Parse("file://" + filename));
|
||||||
try
|
try
|
||||||
|
@ -16,20 +16,18 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
using KeePassLib.Serialization;
|
||||||
using Android.Widget;
|
using Android.Preferences;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
#if NoNet
|
#if NoNet
|
||||||
|
/// <summary>
|
||||||
|
/// Static strings containing App names for the Offline ("nonet") release
|
||||||
|
/// </summary>
|
||||||
public static class AppNames
|
public static class AppNames
|
||||||
{
|
{
|
||||||
public const string AppName = "@string/app_name_nonet";
|
public const string AppName = "@string/app_name_nonet";
|
||||||
@ -38,6 +36,9 @@ namespace keepass2android
|
|||||||
public const string PackagePart = "keepass2android_nonet";
|
public const string PackagePart = "keepass2android_nonet";
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
/// <summary>
|
||||||
|
/// Static strings containing App names for the Online release
|
||||||
|
/// </summary>
|
||||||
public static class AppNames
|
public static class AppNames
|
||||||
{
|
{
|
||||||
public const string AppName = "@string/app_name";
|
public const string AppName = "@string/app_name";
|
||||||
@ -46,16 +47,185 @@ namespace keepass2android
|
|||||||
public const string PackagePart = "keepass2android";
|
public const string PackagePart = "keepass2android";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/// <summary>
|
||||||
|
/// Main implementation of the IKp2aApp interface for usage in the real app.
|
||||||
|
/// </summary>
|
||||||
|
public class Kp2aApp: IKp2aApp
|
||||||
|
{
|
||||||
|
public bool IsShutdown()
|
||||||
|
{
|
||||||
|
return _shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
///Application class for Keepass2Android: Contains static Database variable to be used by all components.
|
public void SetShutdown()
|
||||||
|
{
|
||||||
|
_shutdown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearShutdown()
|
||||||
|
{
|
||||||
|
_shutdown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Database _db;
|
||||||
|
private bool _shutdown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// See comments to EntryEditActivityState.
|
||||||
|
/// </summary>
|
||||||
|
internal EntryEditActivityState EntryEditActivityState = null;
|
||||||
|
|
||||||
|
public FileDbHelper FileDbHelper;
|
||||||
|
|
||||||
|
public Database GetDb()
|
||||||
|
{
|
||||||
|
if (_db == null)
|
||||||
|
{
|
||||||
|
_db = CreateNewDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool GetBooleanPreference(PreferenceKey key)
|
||||||
|
{
|
||||||
|
Context ctx = Application.Context;
|
||||||
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case PreferenceKey.remember_keyfile:
|
||||||
|
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.keyfile_key), ctx.Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
||||||
|
case PreferenceKey.UseFileTransactions:
|
||||||
|
return prefs.GetBoolean(ctx.Resources.GetString(Resource.String.UseFileTransactions_key), true);
|
||||||
|
default:
|
||||||
|
throw new Exception("unexpected key!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void CheckForOpenFileChanged(Activity activity)
|
||||||
|
{
|
||||||
|
if (_db.DidOpenFileChange())
|
||||||
|
{
|
||||||
|
if (_db.ReloadRequested)
|
||||||
|
{
|
||||||
|
activity.SetResult(KeePass.ExitReloadDb);
|
||||||
|
activity.Finish();
|
||||||
|
}
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
|
||||||
|
|
||||||
|
builder.SetMessage(activity.GetString(Resource.String.AskReloadFile));
|
||||||
|
|
||||||
|
builder.SetPositiveButton(activity.GetString(Android.Resource.String.Yes),
|
||||||
|
(dlgSender, dlgEvt) =>
|
||||||
|
{
|
||||||
|
_db.ReloadRequested = true;
|
||||||
|
activity.SetResult(KeePass.ExitReloadDb);
|
||||||
|
activity.Finish();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), (dlgSender, dlgEvt) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Dialog dialog = builder.Create();
|
||||||
|
dialog.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile)
|
||||||
|
{
|
||||||
|
FileDbHelper.CreateFile(ioc, keyfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetResourceString(UiStringKey key)
|
||||||
|
{
|
||||||
|
var field = typeof (Resource.String).GetField(key.ToString());
|
||||||
|
if (field == null)
|
||||||
|
throw new Exception("Invalid key " + key);
|
||||||
|
return Application.Context.GetString((int)field.GetValue(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey,
|
||||||
|
EventHandler<DialogClickEventArgs> yesHandler,
|
||||||
|
EventHandler<DialogClickEventArgs> noHandler,
|
||||||
|
EventHandler<DialogClickEventArgs> cancelHandler,
|
||||||
|
Context ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||||
|
builder.SetTitle(GetResourceString(titleKey));
|
||||||
|
|
||||||
|
builder.SetMessage(GetResourceString(messageKey));
|
||||||
|
|
||||||
|
builder.SetPositiveButton(Resource.String.yes, yesHandler);
|
||||||
|
|
||||||
|
builder.SetNegativeButton(Resource.String.no, noHandler);
|
||||||
|
|
||||||
|
builder.SetNeutralButton(ctx.GetString(Android.Resource.String.Cancel),
|
||||||
|
cancelHandler);
|
||||||
|
|
||||||
|
Dialog dialog = builder.Create();
|
||||||
|
dialog.Show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal void OnTerminate()
|
||||||
|
{
|
||||||
|
if (_db != null)
|
||||||
|
{
|
||||||
|
_db.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileDbHelper != null && FileDbHelper.IsOpen())
|
||||||
|
{
|
||||||
|
FileDbHelper.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void OnCreate(Application app)
|
||||||
|
{
|
||||||
|
FileDbHelper = new FileDbHelper(app);
|
||||||
|
FileDbHelper.Open();
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
foreach (UiStringKey key in Enum.GetValues(typeof(UiStringKey)))
|
||||||
|
{
|
||||||
|
GetResourceString(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
this should case a compiler error when switching to release (and thus ensure DEBUG is defined in DEBUG)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Database CreateNewDatabase()
|
||||||
|
{
|
||||||
|
_db = new Database(new DrawableFactory(), this);
|
||||||
|
return _db;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///Application class for Keepass2Android: Contains static Database variable to be used by all components.
|
||||||
#if NoNet
|
#if NoNet
|
||||||
[Application(Debuggable=false, Label=AppNames.AppName)]
|
[Application(Debuggable=false, Label=AppNames.AppName)]
|
||||||
#else
|
#else
|
||||||
#if RELEASE
|
#if RELEASE
|
||||||
[Application(Debuggable=false, Label=AppNames.AppName)]
|
[Application(Debuggable=false, Label=AppNames.AppName)]
|
||||||
#else
|
#else
|
||||||
[Application(Debuggable=true, Label=AppNames.AppName)]
|
[Application(Debuggable = true, Label = AppNames.AppName)]
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
public class App : Application {
|
public class App : Application {
|
||||||
|
|
||||||
@ -64,63 +234,24 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Database db;
|
public static readonly Kp2aApp Kp2a = new Kp2aApp();
|
||||||
private static bool shutdown = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// See comments to EntryEditActivityState.
|
|
||||||
/// </summary>
|
|
||||||
internal static EntryEditActivityState entryEditActivityState = null;
|
|
||||||
|
|
||||||
public static FileDbHelper fileDbHelper;
|
|
||||||
|
|
||||||
public static Database getDB() {
|
|
||||||
if ( db == null ) {
|
|
||||||
db = new Database();
|
|
||||||
}
|
|
||||||
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setDB(Database d) {
|
|
||||||
db = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool isShutdown() {
|
|
||||||
return shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setShutdown() {
|
|
||||||
shutdown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clearShutdown() {
|
|
||||||
shutdown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnCreate() {
|
public override void OnCreate() {
|
||||||
base.OnCreate();
|
base.OnCreate();
|
||||||
|
|
||||||
Android.Util.Log.Debug("DEBUG","Creating application");
|
Android.Util.Log.Debug("DEBUG","Creating application");
|
||||||
|
|
||||||
fileDbHelper = new FileDbHelper(this);
|
Kp2a.OnCreate(this);
|
||||||
fileDbHelper.open();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnTerminate() {
|
public override void OnTerminate() {
|
||||||
base.OnTerminate();
|
base.OnTerminate();
|
||||||
Android.Util.Log.Debug("DEBUG","Terminating application");
|
Android.Util.Log.Debug("DEBUG","Terminating application");
|
||||||
if ( db != null ) {
|
Kp2a.OnTerminate();
|
||||||
db.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fileDbHelper != null && fileDbHelper.isOpen() ) {
|
|
||||||
fileDbHelper.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
//
|
//
|
||||||
using System;
|
using System;
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -64,8 +63,11 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// base class for "tasks": this are things the user wants to do and which require several activities
|
/// base class for "tasks": these are things the user wants to do and which require several activities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// Therefore AppTasks need to be serializable to bundles and intents to "survive" saving to instance state and changing activities.
|
||||||
|
/// An AppTask has a type and may have several parameters ("extras").
|
||||||
|
/// Activities call the task at special points so tasks can change the behaviour at these points.
|
||||||
public abstract class AppTask
|
public abstract class AppTask
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -105,7 +107,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public const String AppTask_key = "KP2A_APPTASK";
|
public const String AppTaskKey = "KP2A_APPTASK";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should be used in OnCreate to (re)create a task
|
/// Should be used in OnCreate to (re)create a task
|
||||||
@ -116,13 +118,13 @@ namespace keepass2android
|
|||||||
AppTask task;
|
AppTask task;
|
||||||
if (savedInstanceState != null)
|
if (savedInstanceState != null)
|
||||||
{
|
{
|
||||||
task = AppTask.CreateFromBundle(savedInstanceState);
|
task = CreateFromBundle(savedInstanceState);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
task = AppTask.CreateFromIntent(intent);
|
task = CreateFromIntent(intent);
|
||||||
}
|
}
|
||||||
Android.Util.Log.Debug("DEBUG", "Loaded task " + task.ToString());
|
Android.Util.Log.Debug("DEBUG", "Loaded task " + task);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,20 +138,23 @@ namespace keepass2android
|
|||||||
if (b == null)
|
if (b == null)
|
||||||
return new NullTask();
|
return new NullTask();
|
||||||
|
|
||||||
string taskType = b.GetString(AppTask_key);
|
string taskType = b.GetString(AppTaskKey);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(taskType))
|
if (string.IsNullOrEmpty(taskType))
|
||||||
return new NullTask();
|
return new NullTask();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AppTask task = (AppTask)Activator.CreateInstance(Type.GetType("keepass2android."+taskType));
|
Type type = Type.GetType("keepass2android." + taskType);
|
||||||
|
if (type == null)
|
||||||
|
return new NullTask();
|
||||||
|
AppTask task = (AppTask)Activator.CreateInstance(type);
|
||||||
task.Setup(b);
|
task.Setup(b);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Android.Util.Log.Debug("DEBUG", "Cannot convert " + taskType + " in task: " + e.ToString());
|
Android.Util.Log.Debug("DEBUG", "Cannot convert " + taskType + " in task: " + e);
|
||||||
return new NullTask();
|
return new NullTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +165,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ToIntent(Intent intent)
|
public void ToIntent(Intent intent)
|
||||||
{
|
{
|
||||||
AppTask.GetTypeExtra(GetType()).ToIntent(intent);
|
GetTypeExtra(GetType()).ToIntent(intent);
|
||||||
|
|
||||||
foreach (IExtra extra in Extras)
|
foreach (IExtra extra in Extras)
|
||||||
{
|
{
|
||||||
@ -173,7 +178,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ToBundle(Bundle bundle)
|
public void ToBundle(Bundle bundle)
|
||||||
{
|
{
|
||||||
AppTask.GetTypeExtra(GetType()).ToBundle(bundle);
|
GetTypeExtra(GetType()).ToBundle(bundle);
|
||||||
|
|
||||||
foreach (IExtra extra in Extras)
|
foreach (IExtra extra in Extras)
|
||||||
{
|
{
|
||||||
@ -187,7 +192,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
static IExtra GetTypeExtra(Type type)
|
static IExtra GetTypeExtra(Type type)
|
||||||
{
|
{
|
||||||
return new StringExtra() { Key=AppTask_key, Value=type.Name};
|
return new StringExtra { Key=AppTaskKey, Value=type.Name};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -205,7 +210,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class SearchUrlTask: AppTask
|
public class SearchUrlTask: AppTask
|
||||||
{
|
{
|
||||||
public const String UrlToSearch_key = "UrlToSearch";
|
public const String UrlToSearchKey = "UrlToSearch";
|
||||||
|
|
||||||
public string UrlToSearchFor
|
public string UrlToSearchFor
|
||||||
{
|
{
|
||||||
@ -215,13 +220,13 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override void Setup(Bundle b)
|
public override void Setup(Bundle b)
|
||||||
{
|
{
|
||||||
UrlToSearchFor = b.GetString(UrlToSearch_key);
|
UrlToSearchFor = b.GetString(UrlToSearchKey);
|
||||||
}
|
}
|
||||||
public override IEnumerable<IExtra> Extras
|
public override IEnumerable<IExtra> Extras
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new StringExtra() { Key=UrlToSearch_key, Value = UrlToSearchFor };
|
yield return new StringExtra { Key=UrlToSearchKey, Value = UrlToSearchFor };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void AfterUnlockDatabase(PasswordActivity act)
|
public override void AfterUnlockDatabase(PasswordActivity act)
|
||||||
@ -254,7 +259,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CreateEntryThenCloseTask: AppTask
|
public class CreateEntryThenCloseTask: AppTask
|
||||||
{
|
{
|
||||||
public const String Url_key = "CreateEntry_Url";
|
public const String UrlKey = "CreateEntry_Url";
|
||||||
|
|
||||||
public string Url
|
public string Url
|
||||||
{
|
{
|
||||||
@ -264,14 +269,13 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override void Setup(Bundle b)
|
public override void Setup(Bundle b)
|
||||||
{
|
{
|
||||||
Url = b.GetString(Url_key);
|
Url = b.GetString(UrlKey);
|
||||||
}
|
}
|
||||||
public override IEnumerable<IExtra> Extras
|
public override IEnumerable<IExtra> Extras
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new StringExtra() { Key = Url_key, Value = Url };
|
yield return new StringExtra { Key = UrlKey, Value = Url };
|
||||||
yield break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +289,7 @@ namespace keepass2android
|
|||||||
public override void AfterAddNewEntry(EntryEditActivity entryEditActivity, PwEntry newEntry)
|
public override void AfterAddNewEntry(EntryEditActivity entryEditActivity, PwEntry newEntry)
|
||||||
{
|
{
|
||||||
EntryActivity.Launch(entryEditActivity, newEntry, -1, new SelectEntryTask());
|
EntryActivity.Launch(entryEditActivity, newEntry, -1, new SelectEntryTask());
|
||||||
entryEditActivity.SetResult(KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE);
|
entryEditActivity.SetResult(KeePass.ExitCloseAfterTaskComplete);
|
||||||
//no need to call Finish here, that's done in EntryEditActivity ("closeOrShowError")
|
//no need to call Finish here, that's done in EntryEditActivity ("closeOrShowError")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,39 +16,32 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ActivityCompat {
|
public class ActivityCompat {
|
||||||
private static MethodInfo invalidateOptMenuMethod;
|
private static MethodInfo _invalidateOptMenuMethod;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void invalidateOptionsMenu(Activity act) {
|
public static void InvalidateOptionsMenu(Activity act) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
invalidateOptMenuMethod = act.GetType ().GetMethod("InvalidateOptionsMenu", new Type[]{});
|
_invalidateOptMenuMethod = act.GetType().GetMethod("InvalidateOptionsMenu", new Type[]{});
|
||||||
} catch (Exception) {
|
} catch (Exception)
|
||||||
// Do nothing if method dosen't exist
|
{
|
||||||
|
// Do nothing if method doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidateOptMenuMethod != null) {
|
if (_invalidateOptMenuMethod != null) {
|
||||||
try {
|
try {
|
||||||
invalidateOptMenuMethod.Invoke(act, (new Object[]{}));
|
_invalidateOptMenuMethod.Invoke(act, (new Object[]{}));
|
||||||
} catch (Exception) {
|
} catch (Exception)
|
||||||
// Do nothing
|
{
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
@ -34,7 +25,7 @@ namespace keepass2android
|
|||||||
public class EditorCompat {
|
public class EditorCompat {
|
||||||
private static MethodInfo applyMethod;
|
private static MethodInfo applyMethod;
|
||||||
|
|
||||||
public static void apply (ISharedPreferencesEditor edit)
|
public static void Apply (ISharedPreferencesEditor edit)
|
||||||
{
|
{
|
||||||
if (applyMethod == null) {
|
if (applyMethod == null) {
|
||||||
try {
|
try {
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.Serialization;
|
|
||||||
using KeePassLib.Keys;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
|
|
||||||
public class CreateDB : RunnableOnFinish {
|
|
||||||
|
|
||||||
private const int DEFAULT_ENCRYPTION_ROUNDS = 1000;
|
|
||||||
|
|
||||||
private IOConnectionInfo mIoc;
|
|
||||||
private bool mDontSave;
|
|
||||||
private Context mCtx;
|
|
||||||
|
|
||||||
public CreateDB(Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) {
|
|
||||||
mCtx = ctx;
|
|
||||||
mIoc = ioc;
|
|
||||||
mDontSave = dontSave;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void run() {
|
|
||||||
// Create new database record
|
|
||||||
Database db = new Database();
|
|
||||||
App.setDB(db);
|
|
||||||
|
|
||||||
db.pm = new KeePassLib.PwDatabase();
|
|
||||||
//Key will be changed/created immediately after creation:
|
|
||||||
CompositeKey tempKey = new CompositeKey();
|
|
||||||
db.pm.New(mIoc, tempKey);
|
|
||||||
|
|
||||||
|
|
||||||
db.pm.KeyEncryptionRounds = DEFAULT_ENCRYPTION_ROUNDS;
|
|
||||||
db.pm.Name = "Keepass2Android Password Database";
|
|
||||||
|
|
||||||
|
|
||||||
// Set Database state
|
|
||||||
db.root = db.pm.RootGroup;
|
|
||||||
db.mIoc = mIoc;
|
|
||||||
db.Loaded = true;
|
|
||||||
db.searchHelper = new SearchDbHelper(mCtx);
|
|
||||||
|
|
||||||
// Add a couple default groups
|
|
||||||
AddGroup internet = AddGroup.getInstance(mCtx, db, "Internet", 1, db.pm.RootGroup, null, true);
|
|
||||||
internet.run();
|
|
||||||
AddGroup email = AddGroup.getInstance(mCtx, db, "eMail", 19, db.pm.RootGroup, null, true);
|
|
||||||
email.run();
|
|
||||||
|
|
||||||
// Commit changes
|
|
||||||
SaveDB save = new SaveDB(mCtx, db, mFinish, mDontSave);
|
|
||||||
mFinish = null;
|
|
||||||
save.run();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
|||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
public abstract class DeleteRunnable : RunnableOnFinish
|
|
||||||
{
|
|
||||||
public DeleteRunnable(OnFinish finish):base(finish)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Database mDb;
|
|
||||||
|
|
||||||
protected Context mCtx;
|
|
||||||
|
|
||||||
protected void setMembers(Context ctx, Database db)
|
|
||||||
{
|
|
||||||
mCtx = ctx;
|
|
||||||
mDb = db;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private bool mDeletePermanently = true;
|
|
||||||
|
|
||||||
public bool DeletePermanently
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return mDeletePermanently;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
mDeletePermanently = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract bool CanRecycle
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool CanRecycleGroup(PwGroup pgParent)
|
|
||||||
{
|
|
||||||
bool bShiftPressed = false;
|
|
||||||
PwDatabase pd = mDb.pm;
|
|
||||||
PwGroup pgRecycleBin = pd.RootGroup.FindGroup(pd.RecycleBinUuid, true);
|
|
||||||
bool bPermanent = false;
|
|
||||||
if (pgParent != null)
|
|
||||||
{
|
|
||||||
if (pd.RecycleBinEnabled == false)
|
|
||||||
bPermanent = true;
|
|
||||||
else if (bShiftPressed)
|
|
||||||
bPermanent = true;
|
|
||||||
else if (pgRecycleBin == null)
|
|
||||||
{
|
|
||||||
} // Recycle
|
|
||||||
else if (pgParent == pgRecycleBin)
|
|
||||||
bPermanent = true;
|
|
||||||
else if (pgParent.IsContainedIn(pgRecycleBin))
|
|
||||||
bPermanent = true;
|
|
||||||
}
|
|
||||||
return !bPermanent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void EnsureRecycleBin(ref PwGroup pgRecycleBin,
|
|
||||||
ref bool bGroupListUpdateRequired)
|
|
||||||
{
|
|
||||||
if ((mDb == null) || (mDb.pm == null)) { return; }
|
|
||||||
|
|
||||||
if(pgRecycleBin == mDb.pm.RootGroup)
|
|
||||||
{
|
|
||||||
pgRecycleBin = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pgRecycleBin == null)
|
|
||||||
{
|
|
||||||
pgRecycleBin = new PwGroup(true, true, mCtx.GetString(Resource.String.RecycleBin),
|
|
||||||
PwIcon.TrashBin);
|
|
||||||
pgRecycleBin.EnableAutoType = false;
|
|
||||||
pgRecycleBin.EnableSearching = false;
|
|
||||||
pgRecycleBin.IsExpanded = false;
|
|
||||||
mDb.pm.RootGroup.AddGroup(pgRecycleBin, true);
|
|
||||||
|
|
||||||
mDb.pm.RecycleBinUuid = pgRecycleBin.Uuid;
|
|
||||||
|
|
||||||
bGroupListUpdateRequired = true;
|
|
||||||
}
|
|
||||||
else { System.Diagnostics.Debug.Assert(pgRecycleBin.Uuid.EqualsValue(mDb.pm.RecycleBinUuid)); }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract int QuestionsResourceId
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start()
|
|
||||||
{
|
|
||||||
if (CanRecycle)
|
|
||||||
{
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mCtx);
|
|
||||||
builder.SetTitle(mCtx.GetString(Resource.String.AskDeletePermanently_title));
|
|
||||||
|
|
||||||
builder.SetMessage(mCtx.GetString(QuestionsResourceId));
|
|
||||||
|
|
||||||
builder.SetPositiveButton(Resource.String.yes, new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
|
||||||
{
|
|
||||||
DeletePermanently = true;
|
|
||||||
ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database);
|
|
||||||
pt.run();
|
|
||||||
}));
|
|
||||||
|
|
||||||
builder.SetNegativeButton(Resource.String.no, new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {
|
|
||||||
DeletePermanently = false;
|
|
||||||
ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database);
|
|
||||||
pt.run();
|
|
||||||
}));
|
|
||||||
|
|
||||||
builder.SetNeutralButton(mCtx.GetString(Android.Resource.String.Cancel),
|
|
||||||
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}));
|
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
|
||||||
dialog.Show();
|
|
||||||
|
|
||||||
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
ProgressTask pt = new ProgressTask(mCtx, this, Resource.String.saving_database);
|
|
||||||
pt.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 Android.Preferences;
|
|
||||||
using KeePassLib.Serialization;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
public class LoadDB : RunnableOnFinish {
|
|
||||||
private IOConnectionInfo mIoc;
|
|
||||||
private String mPass;
|
|
||||||
private String mKey;
|
|
||||||
private Database mDb;
|
|
||||||
private Context mCtx;
|
|
||||||
private bool mRememberKeyfile;
|
|
||||||
|
|
||||||
public LoadDB(Database db, Context ctx, IOConnectionInfo ioc, String pass, String key, OnFinish finish): base(finish)
|
|
||||||
{
|
|
||||||
mDb = db;
|
|
||||||
mCtx = ctx;
|
|
||||||
mIoc = ioc;
|
|
||||||
mPass = pass;
|
|
||||||
mKey = key;
|
|
||||||
|
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
|
||||||
mRememberKeyfile = prefs.GetBoolean(ctx.GetString(Resource.String.keyfile_key), ctx.Resources.GetBoolean(Resource.Boolean.keyfile_default));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void run ()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
mDb.LoadData (mCtx, mIoc, mPass, mKey, mStatus);
|
|
||||||
|
|
||||||
saveFileData (mIoc, mKey);
|
|
||||||
|
|
||||||
} catch (KeyFileException) {
|
|
||||||
finish(false, /*TODO Localize: use Keepass error text KPRes.KeyFileError (including "or invalid format")*/ mCtx.GetString(Resource.String.keyfile_does_not_exist));
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
finish(false, "An error occured: " + e.Message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* catch (InvalidPasswordException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.InvalidPassword));
|
|
||||||
return;
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.FileNotFound));
|
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
|
||||||
finish(false, e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (KeyFileEmptyException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.keyfile_is_empty));
|
|
||||||
return;
|
|
||||||
} catch (InvalidAlgorithmException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.invalid_algorithm));
|
|
||||||
return;
|
|
||||||
} catch (InvalidKeyFileException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.keyfile_does_not_exist));
|
|
||||||
return;
|
|
||||||
} catch (InvalidDBSignatureException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.invalid_db_sig));
|
|
||||||
return;
|
|
||||||
} catch (InvalidDBVersionException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.unsupported_db_version));
|
|
||||||
return;
|
|
||||||
} catch (InvalidDBException e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.error_invalid_db));
|
|
||||||
return;
|
|
||||||
} catch (OutOfMemoryError e) {
|
|
||||||
finish(false, mCtx.GetString(Resource.String.error_out_of_memory));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
finish(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveFileData(IOConnectionInfo ioc, String key) {
|
|
||||||
FileDbHelper db = App.fileDbHelper;
|
|
||||||
|
|
||||||
if ( ! mRememberKeyfile ) {
|
|
||||||
key = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
db.createFile(ioc, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
|
|
||||||
public abstract class RunnableOnFinish {
|
|
||||||
|
|
||||||
public OnFinish mFinish;
|
|
||||||
public UpdateStatus mStatus;
|
|
||||||
|
|
||||||
public RunnableOnFinish(OnFinish finish) {
|
|
||||||
mFinish = finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void finish(bool result, String message) {
|
|
||||||
if ( mFinish != null ) {
|
|
||||||
mFinish.setResult(result, message);
|
|
||||||
mFinish.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void finish(bool result) {
|
|
||||||
if ( mFinish != null ) {
|
|
||||||
mFinish.setResult(result);
|
|
||||||
mFinish.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(UpdateStatus status) {
|
|
||||||
mStatus = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public void run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -15,22 +15,18 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dialog to offer to install OpenIntent file manager if there's no other browser installed
|
||||||
|
/// </summary>
|
||||||
public class BrowserDialog : Dialog {
|
public class BrowserDialog : Dialog {
|
||||||
|
|
||||||
public BrowserDialog(Context context) : base(context)
|
public BrowserDialog(Context context) : base(context)
|
||||||
@ -43,31 +39,28 @@ namespace keepass2android
|
|||||||
SetTitle(Resource.String.file_browser);
|
SetTitle(Resource.String.file_browser);
|
||||||
|
|
||||||
Button cancel = (Button) FindViewById(Resource.Id.cancel);
|
Button cancel = (Button) FindViewById(Resource.Id.cancel);
|
||||||
cancel.Click += (sender, e) => {
|
cancel.Click += (sender, e) => Cancel();
|
||||||
this.Cancel();
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
Button market = (Button) FindViewById(Resource.Id.install_market);
|
Button market = (Button) FindViewById(Resource.Id.install_market);
|
||||||
market.Click += (sender, e) => {
|
market.Click += (sender, e) => {
|
||||||
Util.gotoUrl(Context, Resource.String.oi_filemanager_market);
|
Util.gotoUrl(Context, Resource.String.oi_filemanager_market);
|
||||||
this.Cancel();
|
Cancel();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
if (!isMarketInstalled()) {
|
if (!IsMarketInstalled()) {
|
||||||
market.Visibility = ViewStates.Gone;
|
market.Visibility = ViewStates.Gone;
|
||||||
}
|
}
|
||||||
|
|
||||||
Button web = (Button) FindViewById(Resource.Id.install_web);
|
Button web = (Button) FindViewById(Resource.Id.install_web);
|
||||||
web.Click += (sender, e) => {
|
web.Click += (sender, e) => {
|
||||||
Util.gotoUrl(Context, Resource.String.oi_filemanager_web);
|
Util.gotoUrl(Context, Resource.String.oi_filemanager_web);
|
||||||
this.Cancel();
|
Cancel();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool isMarketInstalled() {
|
private bool IsMarketInstalled() {
|
||||||
Android.Content.PM.PackageManager pm = Context.PackageManager;
|
PackageManager pm = Context.PackageManager;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pm.GetPackageInfo("com.android.vending", 0);
|
pm.GetPackageInfo("com.android.vending", 0);
|
||||||
|
@ -16,65 +16,56 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Database;
|
using Android.Database;
|
||||||
using Android.Database.Sqlite;
|
using Android.Database.Sqlite;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class to store the recent files in a database
|
||||||
|
/// </summary>
|
||||||
public class FileDbHelper {
|
public class FileDbHelper {
|
||||||
|
|
||||||
public const String LAST_FILENAME = "lastFile";
|
public const String LastFilename = "lastFile";
|
||||||
public const String LAST_KEYFILE = "lastKey";
|
public const String LastKeyfile = "lastKey";
|
||||||
|
|
||||||
private const String DATABASE_NAME = "keepass2android";
|
private const String DatabaseName = "keepass2android";
|
||||||
private const String FILE_TABLE = "files";
|
private const String FileTable = "files";
|
||||||
private const int DATABASE_VERSION = 1;
|
private const int DatabaseVersion = 1;
|
||||||
|
|
||||||
private const int MAX_FILES = 5;
|
private const int MaxFiles = 5;
|
||||||
|
|
||||||
public const String KEY_FILE_ID = "_id";
|
public const String KeyFileId = "_id";
|
||||||
public const String KEY_FILE_FILENAME = "fileName";
|
public const String KeyFileFilename = "fileName";
|
||||||
public const String KEY_FILE_USERNAME = "username";
|
public const String KeyFileUsername = "username";
|
||||||
public const String KEY_FILE_PASSWORD = "password";
|
public const String KeyFilePassword = "password";
|
||||||
public const String KEY_FILE_CREDSAVEMODE = "credSaveMode";
|
public const String KeyFileCredsavemode = "credSaveMode";
|
||||||
public const String KEY_FILE_KEYFILE = "keyFile";
|
public const String KeyFileKeyfile = "keyFile";
|
||||||
public const String KEY_FILE_UPDATED = "updated";
|
public const String KeyFileUpdated = "updated";
|
||||||
|
|
||||||
private const String DATABASE_CREATE =
|
private const String DatabaseCreate =
|
||||||
"create table " + FILE_TABLE + " ( " + KEY_FILE_ID + " integer primary key autoincrement, "
|
"create table " + FileTable + " ( " + KeyFileId + " integer primary key autoincrement, "
|
||||||
+ KEY_FILE_FILENAME + " text not null, "
|
+ KeyFileFilename + " text not null, "
|
||||||
+ KEY_FILE_KEYFILE + " text, "
|
+ KeyFileKeyfile + " text, "
|
||||||
+ KEY_FILE_USERNAME + " text, "
|
+ KeyFileUsername + " text, "
|
||||||
+ KEY_FILE_PASSWORD + " text, "
|
+ KeyFilePassword + " text, "
|
||||||
+ KEY_FILE_CREDSAVEMODE + " integer not null,"
|
+ KeyFileCredsavemode + " integer not null,"
|
||||||
+ KEY_FILE_UPDATED + " integer not null);";
|
+ KeyFileUpdated + " integer not null);";
|
||||||
|
|
||||||
private readonly Android.Content.Context mCtx;
|
private readonly Context mCtx;
|
||||||
private DatabaseHelper mDbHelper;
|
private DatabaseHelper mDbHelper;
|
||||||
private SQLiteDatabase mDb;
|
private SQLiteDatabase mDb;
|
||||||
|
|
||||||
private class DatabaseHelper : SQLiteOpenHelper {
|
private class DatabaseHelper : SQLiteOpenHelper {
|
||||||
private readonly Android.Content.Context mCtx;
|
public DatabaseHelper(Context ctx): base(ctx, FileDbHelper.DatabaseName, null, DatabaseVersion) {
|
||||||
|
|
||||||
public DatabaseHelper(Android.Content.Context ctx): base(ctx, DATABASE_NAME, null, DATABASE_VERSION) {
|
|
||||||
|
|
||||||
mCtx = ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void OnCreate(SQLiteDatabase db) {
|
public override void OnCreate(SQLiteDatabase db) {
|
||||||
db.ExecSQL(DATABASE_CREATE);
|
db.ExecSQL(DatabaseCreate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,27 +80,27 @@ namespace keepass2android
|
|||||||
mCtx = ctx;
|
mCtx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileDbHelper open() {
|
public FileDbHelper Open() {
|
||||||
mDbHelper = new DatabaseHelper(mCtx);
|
mDbHelper = new DatabaseHelper(mCtx);
|
||||||
mDb = mDbHelper.WritableDatabase;
|
mDb = mDbHelper.WritableDatabase;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isOpen() {
|
public bool IsOpen() {
|
||||||
return mDb.IsOpen;
|
return mDb.IsOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void Close() {
|
||||||
mDb.Close();
|
mDb.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long createFile(IOConnectionInfo ioc, String keyFile) {
|
public long CreateFile(IOConnectionInfo ioc, String keyFile) {
|
||||||
|
|
||||||
// Check to see if this filename is already used
|
// Check to see if this filename is already used
|
||||||
ICursor cursor;
|
ICursor cursor;
|
||||||
try {
|
try {
|
||||||
cursor = mDb.Query(true, FILE_TABLE, new String[] {KEY_FILE_ID},
|
cursor = mDb.Query(true, FileTable, new[] {KeyFileId},
|
||||||
KEY_FILE_FILENAME + "=?", new String[] {ioc.Path}, null, null, null, null);
|
KeyFileFilename + "=?", new[] {ioc.Path}, null, null, null, null);
|
||||||
} catch (Exception ) {
|
} catch (Exception ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -126,34 +117,34 @@ namespace keepass2android
|
|||||||
// If there is an existing entry update it
|
// If there is an existing entry update it
|
||||||
if ( cursor.Count > 0 ) {
|
if ( cursor.Count > 0 ) {
|
||||||
cursor.MoveToFirst();
|
cursor.MoveToFirst();
|
||||||
long id = cursor.GetLong(cursor.GetColumnIndexOrThrow(KEY_FILE_ID));
|
long id = cursor.GetLong(cursor.GetColumnIndexOrThrow(KeyFileId));
|
||||||
|
|
||||||
ContentValues vals = new ContentValues();
|
var vals = new ContentValues();
|
||||||
vals.Put(KEY_FILE_KEYFILE, keyFile);
|
vals.Put(KeyFileKeyfile, keyFile);
|
||||||
vals.Put(KEY_FILE_UPDATED, Java.Lang.JavaSystem.CurrentTimeMillis());
|
vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());
|
||||||
|
|
||||||
vals.Put(KEY_FILE_USERNAME, iocToStore.UserName);
|
vals.Put(KeyFileUsername, iocToStore.UserName);
|
||||||
vals.Put(KEY_FILE_PASSWORD, iocToStore.Password);
|
vals.Put(KeyFilePassword, iocToStore.Password);
|
||||||
vals.Put(KEY_FILE_CREDSAVEMODE, (int)iocToStore.CredSaveMode);
|
vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);
|
||||||
|
|
||||||
result = mDb.Update(FILE_TABLE, vals, KEY_FILE_ID + " = " + id, null);
|
result = mDb.Update(FileTable, vals, KeyFileId + " = " + id, null);
|
||||||
|
|
||||||
// Otherwise add the new entry
|
// Otherwise add the new entry
|
||||||
} else {
|
} else {
|
||||||
ContentValues vals = new ContentValues();
|
var vals = new ContentValues();
|
||||||
vals.Put(KEY_FILE_FILENAME, ioc.Path);
|
vals.Put(KeyFileFilename, ioc.Path);
|
||||||
vals.Put(KEY_FILE_KEYFILE, keyFile);
|
vals.Put(KeyFileKeyfile, keyFile);
|
||||||
vals.Put(KEY_FILE_USERNAME, iocToStore.UserName);
|
vals.Put(KeyFileUsername, iocToStore.UserName);
|
||||||
vals.Put(KEY_FILE_PASSWORD, iocToStore.Password);
|
vals.Put(KeyFilePassword, iocToStore.Password);
|
||||||
vals.Put(KEY_FILE_CREDSAVEMODE, (int)iocToStore.CredSaveMode);
|
vals.Put(KeyFileCredsavemode, (int)iocToStore.CredSaveMode);
|
||||||
vals.Put(KEY_FILE_UPDATED, Java.Lang.JavaSystem.CurrentTimeMillis());
|
vals.Put(KeyFileUpdated, Java.Lang.JavaSystem.CurrentTimeMillis());
|
||||||
|
|
||||||
result = mDb.Insert(FILE_TABLE, null, vals);
|
result = mDb.Insert(FileTable, null, vals);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Delete all but the last five records
|
// Delete all but the last five records
|
||||||
try {
|
try {
|
||||||
deleteAllBut(MAX_FILES);
|
DeleteAllBut(MaxFiles);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Android.Util.Log.Error("ex",ex.StackTrace);
|
Android.Util.Log.Error("ex",ex.StackTrace);
|
||||||
|
|
||||||
@ -165,53 +156,53 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteAllBut(int limit) {
|
private void DeleteAllBut(int limit) {
|
||||||
ICursor cursor = mDb.Query(FILE_TABLE, new String[] {KEY_FILE_UPDATED}, null, null, null, null, KEY_FILE_UPDATED);
|
ICursor cursor = mDb.Query(FileTable, new[] {KeyFileUpdated}, null, null, null, null, KeyFileUpdated);
|
||||||
|
|
||||||
if ( cursor.Count > limit ) {
|
if ( cursor.Count > limit ) {
|
||||||
cursor.MoveToFirst();
|
cursor.MoveToFirst();
|
||||||
long time = cursor.GetLong(cursor.GetColumnIndexOrThrow(KEY_FILE_UPDATED));
|
long time = cursor.GetLong(cursor.GetColumnIndexOrThrow(KeyFileUpdated));
|
||||||
|
|
||||||
mDb.ExecSQL("DELETE FROM " + FILE_TABLE + " WHERE " + KEY_FILE_UPDATED + "<" + time + ";");
|
mDb.ExecSQL("DELETE FROM " + FileTable + " WHERE " + KeyFileUpdated + "<" + time + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.Close();
|
cursor.Close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAllKeys() {
|
public void DeleteAllKeys() {
|
||||||
ContentValues vals = new ContentValues();
|
var vals = new ContentValues();
|
||||||
vals.Put(KEY_FILE_KEYFILE, "");
|
vals.Put(KeyFileKeyfile, "");
|
||||||
|
|
||||||
mDb.Update(FILE_TABLE, vals, null, null);
|
mDb.Update(FileTable, vals, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteFile(String filename) {
|
public void DeleteFile(String filename) {
|
||||||
mDb.Delete(FILE_TABLE, KEY_FILE_FILENAME + " = ?", new String[] {filename});
|
mDb.Delete(FileTable, KeyFileFilename + " = ?", new[] {filename});
|
||||||
}
|
}
|
||||||
|
|
||||||
static string[] getColumnList()
|
static string[] GetColumnList()
|
||||||
{
|
{
|
||||||
return new String[] {
|
return new[] {
|
||||||
KEY_FILE_ID,
|
KeyFileId,
|
||||||
KEY_FILE_FILENAME,
|
KeyFileFilename,
|
||||||
KEY_FILE_KEYFILE,
|
KeyFileKeyfile,
|
||||||
KEY_FILE_USERNAME,
|
KeyFileUsername,
|
||||||
KEY_FILE_PASSWORD,
|
KeyFilePassword,
|
||||||
KEY_FILE_CREDSAVEMODE
|
KeyFileCredsavemode
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICursor fetchAllFiles() {
|
public ICursor FetchAllFiles()
|
||||||
ICursor ret;
|
{
|
||||||
ret = mDb.Query(FILE_TABLE, getColumnList(),
|
ICursor ret = mDb.Query(FileTable, GetColumnList(),
|
||||||
null, null, null, null, KEY_FILE_UPDATED + " DESC", MAX_FILES.ToString());
|
null, null, null, null, KeyFileUpdated + " DESC", MaxFiles.ToString(CultureInfo.InvariantCulture));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICursor fetchFile(long fileId) {
|
public ICursor FetchFile(long fileId) {
|
||||||
ICursor cursor = mDb.Query(true, FILE_TABLE, getColumnList(),
|
ICursor cursor = mDb.Query(true, FileTable, GetColumnList(),
|
||||||
KEY_FILE_ID + "=" + fileId, null, null, null, null, null);
|
KeyFileId + "=" + fileId, null, null, null, null, null);
|
||||||
|
|
||||||
if ( cursor != null ) {
|
if ( cursor != null ) {
|
||||||
cursor.MoveToFirst();
|
cursor.MoveToFirst();
|
||||||
@ -221,11 +212,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICursor fetchFileByName(string fileName)
|
public ICursor FetchFileByName(string fileName)
|
||||||
{
|
{
|
||||||
|
|
||||||
ICursor cursor = mDb.Query(true, FILE_TABLE, getColumnList(),
|
ICursor cursor = mDb.Query(true, FileTable, GetColumnList(),
|
||||||
KEY_FILE_FILENAME + " like " + DatabaseUtils.SqlEscapeString(fileName) , null, null, null, null, null);
|
KeyFileFilename + " like " + DatabaseUtils.SqlEscapeString(fileName) , null, null, null, null, null);
|
||||||
|
|
||||||
if ( cursor != null ) {
|
if ( cursor != null ) {
|
||||||
cursor.MoveToFirst();
|
cursor.MoveToFirst();
|
||||||
@ -235,9 +226,9 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileByName(String name) {
|
public String GetFileByName(String name) {
|
||||||
ICursor cursor = mDb.Query(true, FILE_TABLE, getColumnList(),
|
ICursor cursor = mDb.Query(true, FileTable, GetColumnList(),
|
||||||
KEY_FILE_FILENAME + "= ?", new String[] {name}, null, null, null, null);
|
KeyFileFilename + "= ?", new[] {name}, null, null, null, null);
|
||||||
|
|
||||||
if ( cursor == null ) {
|
if ( cursor == null ) {
|
||||||
return "";
|
return "";
|
||||||
@ -246,7 +237,7 @@ namespace keepass2android
|
|||||||
String keyfileFilename;
|
String keyfileFilename;
|
||||||
|
|
||||||
if ( cursor.MoveToFirst() ) {
|
if ( cursor.MoveToFirst() ) {
|
||||||
keyfileFilename = cursor.GetString(cursor.GetColumnIndexOrThrow(KEY_FILE_KEYFILE));
|
keyfileFilename = cursor.GetString(cursor.GetColumnIndexOrThrow(KeyFileKeyfile));
|
||||||
} else {
|
} else {
|
||||||
// Cursor is empty
|
// Cursor is empty
|
||||||
keyfileFilename = "";
|
keyfileFilename = "";
|
||||||
@ -255,8 +246,8 @@ namespace keepass2android
|
|||||||
return keyfileFilename;
|
return keyfileFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasRecentFiles() {
|
public bool HasRecentFiles() {
|
||||||
ICursor cursor = fetchAllFiles();
|
ICursor cursor = FetchAllFiles();
|
||||||
|
|
||||||
bool hasRecent = cursor.Count > 0;
|
bool hasRecent = cursor.Count > 0;
|
||||||
cursor.Close();
|
cursor.Close();
|
||||||
@ -264,24 +255,24 @@ namespace keepass2android
|
|||||||
return hasRecent;
|
return hasRecent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOConnectionInfo cursorToIoc(Android.Database.ICursor cursor)
|
public IOConnectionInfo CursorToIoc(ICursor cursor)
|
||||||
{
|
{
|
||||||
if (cursor == null)
|
if (cursor == null)
|
||||||
return null;
|
return null;
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo();
|
var ioc = new IOConnectionInfo
|
||||||
ioc.Path = cursor.GetString(cursor
|
{
|
||||||
.GetColumnIndexOrThrow(FileDbHelper.KEY_FILE_FILENAME));
|
Path = cursor.GetString(cursor
|
||||||
|
.GetColumnIndexOrThrow(KeyFileFilename)),
|
||||||
|
UserName = cursor.GetString(cursor
|
||||||
|
.GetColumnIndexOrThrow(KeyFileUsername)),
|
||||||
|
Password = cursor.GetString(cursor
|
||||||
|
.GetColumnIndexOrThrow(KeyFilePassword)),
|
||||||
|
CredSaveMode = (IOCredSaveMode) cursor.GetInt(cursor
|
||||||
|
.GetColumnIndexOrThrow(KeyFileCredsavemode)),
|
||||||
|
CredProtMode = IOCredProtMode.Obf
|
||||||
|
};
|
||||||
|
|
||||||
ioc.UserName = cursor.GetString(cursor
|
ioc.Obfuscate(false);
|
||||||
.GetColumnIndexOrThrow(FileDbHelper.KEY_FILE_USERNAME));
|
|
||||||
|
|
||||||
ioc.Password = cursor.GetString(cursor
|
|
||||||
.GetColumnIndexOrThrow(FileDbHelper.KEY_FILE_PASSWORD));
|
|
||||||
|
|
||||||
ioc.CredSaveMode = (IOCredSaveMode)cursor.GetInt(cursor
|
|
||||||
.GetColumnIndexOrThrow(FileDbHelper.KEY_FILE_CREDSAVEMODE));
|
|
||||||
ioc.CredProtMode = IOCredProtMode.Obf;
|
|
||||||
ioc.Obfuscate(false);
|
|
||||||
return ioc;
|
return ioc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,6 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
@ -27,13 +23,13 @@ using Android.Runtime;
|
|||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.Views.InputMethods;
|
|
||||||
using System.IO;
|
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Activity to select the file to use
|
||||||
|
/// </summary>
|
||||||
[Activity (Label = "@string/app_name",
|
[Activity (Label = "@string/app_name",
|
||||||
ConfigurationChanges=ConfigChanges.Orientation|
|
ConfigurationChanges=ConfigChanges.Orientation|
|
||||||
ConfigChanges.KeyboardHidden,
|
ConfigChanges.KeyboardHidden,
|
||||||
@ -54,21 +50,21 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int CMENU_CLEAR = Menu.First;
|
private const int CmenuClear = Menu.First;
|
||||||
|
|
||||||
const string BundleKey_RecentMode = "RecentMode";
|
const string BundleKeyRecentMode = "RecentMode";
|
||||||
|
|
||||||
private FileDbHelper mDbHelper;
|
private FileDbHelper _DbHelper;
|
||||||
|
|
||||||
private bool recentMode = false;
|
private bool _recentMode;
|
||||||
view.FileSelectButtons fileSelectButtons;
|
view.FileSelectButtons _fileSelectButtons;
|
||||||
bool createdWithActivityResult = false;
|
bool _createdWithActivityResult;
|
||||||
|
|
||||||
internal AppTask mAppTask;
|
internal AppTask AppTask;
|
||||||
|
|
||||||
IOConnectionInfo loadIoc(string defaultFileName)
|
IOConnectionInfo LoadIoc(string defaultFileName)
|
||||||
{
|
{
|
||||||
return mDbHelper.cursorToIoc(mDbHelper.fetchFileByName(defaultFileName));
|
return _DbHelper.CursorToIoc(_DbHelper.FetchFileByName(defaultFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowFilenameDialog(bool showOpenButton, bool showCreateButton, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse)
|
void ShowFilenameDialog(bool showOpenButton, bool showCreateButton, bool showBrowseButton, string defaultFilename, string detailsText, int requestCodeBrowse)
|
||||||
@ -94,7 +90,8 @@ namespace keepass2android
|
|||||||
openButton.Click += ( sender, evt) => {
|
openButton.Click += ( sender, evt) => {
|
||||||
String fileName = ((EditText)dialog.FindViewById(Resource.Id.file_filename)).Text;
|
String fileName = ((EditText)dialog.FindViewById(Resource.Id.file_filename)).Text;
|
||||||
|
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo() {
|
IOConnectionInfo ioc = new IOConnectionInfo
|
||||||
|
{
|
||||||
Path = fileName
|
Path = fileName
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,25 +162,23 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prep an object to collect a password once the database has
|
// Prep an object to collect a password once the database has been created
|
||||||
// been created
|
CollectPassword collectPassword = new CollectPassword(
|
||||||
CollectPassword password = new CollectPassword(
|
|
||||||
new LaunchGroupActivity(IOConnectionInfo.FromPath(filename), this), this);
|
new LaunchGroupActivity(IOConnectionInfo.FromPath(filename), this), this);
|
||||||
|
|
||||||
// Create the new database
|
// Create the new database
|
||||||
CreateDB create = new CreateDB(this, IOConnectionInfo.FromPath(filename), password, true);
|
CreateDb create = new CreateDb(App.Kp2a, this, IOConnectionInfo.FromPath(filename), collectPassword, true);
|
||||||
ProgressTask createTask = new ProgressTask(
|
ProgressTask createTask = new ProgressTask(
|
||||||
|
App.Kp2a,
|
||||||
this, create,
|
this, create,
|
||||||
Resource.String.progress_create);
|
UiStringKey.progress_create);
|
||||||
createTask.run();
|
createTask.Run();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Button cancelButton = (Button)dialog.FindViewById(Resource.Id.fnv_cancel);
|
Button cancelButton = (Button)dialog.FindViewById(Resource.Id.fnv_cancel);
|
||||||
cancelButton.Click += (sender, e) => {
|
cancelButton.Click += (sender, e) => dialog.Dismiss();
|
||||||
dialog.Dismiss();
|
|
||||||
};
|
|
||||||
|
|
||||||
ImageButton browseButton = (ImageButton)dialog.FindViewById(Resource.Id.browse_button);
|
ImageButton browseButton = (ImageButton)dialog.FindViewById(Resource.Id.browse_button);
|
||||||
if (!showBrowseButton)
|
if (!showBrowseButton)
|
||||||
@ -208,28 +203,28 @@ namespace keepass2android
|
|||||||
|
|
||||||
if (Intent.Action == Intent.ActionSend)
|
if (Intent.Action == Intent.ActionSend)
|
||||||
{
|
{
|
||||||
mAppTask = new SearchUrlTask() { UrlToSearchFor = Intent.GetStringExtra(Intent.ExtraText) };
|
AppTask = new SearchUrlTask { UrlToSearchFor = Intent.GetStringExtra(Intent.ExtraText) };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mAppTask = AppTask.CreateFromIntent(Intent);
|
AppTask = AppTask.CreateFromIntent(Intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mDbHelper = App.fileDbHelper;
|
_DbHelper = App.Kp2a.FileDbHelper;
|
||||||
if (mDbHelper.hasRecentFiles())
|
if (_DbHelper.HasRecentFiles())
|
||||||
{
|
{
|
||||||
recentMode = true;
|
_recentMode = true;
|
||||||
|
|
||||||
SetContentView(Resource.Layout.file_selection);
|
SetContentView(Resource.Layout.file_selection);
|
||||||
fileSelectButtons = new keepass2android.view.FileSelectButtons(this);
|
_fileSelectButtons = new view.FileSelectButtons(this);
|
||||||
((ListView)FindViewById(Android.Resource.Id.List)).AddFooterView(
|
((ListView)FindViewById(Android.Resource.Id.List)).AddFooterView(
|
||||||
fileSelectButtons);
|
_fileSelectButtons);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
SetContentView(Resource.Layout.file_selection_no_recent);
|
SetContentView(Resource.Layout.file_selection_no_recent);
|
||||||
fileSelectButtons = (view.FileSelectButtons)FindViewById(Resource.Id.file_select);
|
_fileSelectButtons = (view.FileSelectButtons)FindViewById(Resource.Id.file_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,11 +232,11 @@ namespace keepass2android
|
|||||||
Button openFileButton = (Button)FindViewById(Resource.Id.start_open_file);
|
Button openFileButton = (Button)FindViewById(Resource.Id.start_open_file);
|
||||||
|
|
||||||
|
|
||||||
EventHandler openFileButtonClick = (object sender, EventArgs e) =>
|
EventHandler openFileButtonClick = (sender, e) =>
|
||||||
{
|
{
|
||||||
string defaultFilename = Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path);
|
string defaultFilename = Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path);
|
||||||
string detailsText = "";
|
const string detailsText = "";
|
||||||
ShowFilenameDialog(true, false, true, defaultFilename, detailsText, Intents.REQUEST_CODE_FILE_BROWSE_FOR_OPEN);
|
ShowFilenameDialog(true, false, true, defaultFilename, detailsText, Intents.RequestCodeFileBrowseForOpen);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -253,18 +248,12 @@ namespace keepass2android
|
|||||||
openUrlButton.Visibility = ViewStates.Gone;
|
openUrlButton.Visibility = ViewStates.Gone;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EventHandler openUrlButtonClick = (object sender, EventArgs e) =>
|
EventHandler openUrlButtonClick = (sender, e) => ShowFilenameDialog(true, false, false, "", GetString(Resource.String.enter_filename_details_url), Intents.RequestCodeFileBrowseForOpen);
|
||||||
{
|
|
||||||
ShowFilenameDialog(true, false, false, "", GetString(Resource.String.enter_filename_details_url), Intents.REQUEST_CODE_FILE_BROWSE_FOR_OPEN);
|
|
||||||
};
|
|
||||||
openUrlButton.Click += openUrlButtonClick;
|
openUrlButton.Click += openUrlButtonClick;
|
||||||
|
|
||||||
//CREATE NEW
|
//CREATE NEW
|
||||||
Button createNewButton = (Button)FindViewById(Resource.Id.start_create);
|
Button createNewButton = (Button)FindViewById(Resource.Id.start_create);
|
||||||
EventHandler createNewButtonClick = (object sender, EventArgs e) =>
|
EventHandler createNewButtonClick = (sender, e) => ShowFilenameDialog(false, true, true, Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path), "", Intents.RequestCodeFileBrowseForCreate);
|
||||||
{
|
|
||||||
ShowFilenameDialog(false, true, true, Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path), "", Intents.REQUEST_CODE_FILE_BROWSE_FOR_CREATE);
|
|
||||||
};
|
|
||||||
createNewButton.Click += createNewButtonClick;
|
createNewButton.Click += createNewButtonClick;
|
||||||
|
|
||||||
/*//CREATE + IMPORT
|
/*//CREATE + IMPORT
|
||||||
@ -281,14 +270,14 @@ namespace keepass2android
|
|||||||
|
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
fillData();
|
FillData();
|
||||||
|
|
||||||
RegisterForContextMenu(ListView);
|
RegisterForContextMenu(ListView);
|
||||||
|
|
||||||
if (savedInstanceState != null)
|
if (savedInstanceState != null)
|
||||||
{
|
{
|
||||||
mAppTask = AppTask.CreateFromBundle(savedInstanceState);
|
AppTask = AppTask.CreateFromBundle(savedInstanceState);
|
||||||
recentMode = savedInstanceState.GetBoolean(BundleKey_RecentMode, recentMode);
|
_recentMode = savedInstanceState.GetBoolean(BundleKeyRecentMode, _recentMode);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -299,65 +288,64 @@ namespace keepass2android
|
|||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
mAppTask.ToBundle(outState);
|
AppTask.ToBundle(outState);
|
||||||
outState.PutBoolean(BundleKey_RecentMode, recentMode);
|
outState.PutBoolean(BundleKeyRecentMode, _recentMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LaunchGroupActivity : FileOnFinish {
|
private class LaunchGroupActivity : FileOnFinish {
|
||||||
|
readonly FileSelectActivity _activity;
|
||||||
FileSelectActivity activity;
|
private readonly IOConnectionInfo _ioc;
|
||||||
private IOConnectionInfo mIoc;
|
|
||||||
|
|
||||||
public LaunchGroupActivity(IOConnectionInfo ioc, FileSelectActivity activity): base(null) {
|
public LaunchGroupActivity(IOConnectionInfo ioc, FileSelectActivity activity): base(null) {
|
||||||
|
|
||||||
this.activity = activity;
|
_activity = activity;
|
||||||
mIoc = ioc;
|
_ioc = ioc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if (mSuccess) {
|
if (Success) {
|
||||||
// Add to recent files
|
// Add to recent files
|
||||||
FileDbHelper dbHelper = App.fileDbHelper;
|
FileDbHelper dbHelper = App.Kp2a.FileDbHelper;
|
||||||
|
|
||||||
//TODO: getFilename always returns "" -> bug?
|
//TODO: getFilename always returns "" -> bug?
|
||||||
dbHelper.createFile(mIoc, getFilename());
|
dbHelper.CreateFile(_ioc, Filename);
|
||||||
|
|
||||||
GroupActivity.Launch(activity, activity.mAppTask);
|
GroupActivity.Launch(_activity, _activity.AppTask);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
IOConnection.DeleteFile(mIoc);
|
IOConnection.DeleteFile(_ioc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CollectPassword: FileOnFinish {
|
private class CollectPassword: FileOnFinish {
|
||||||
FileSelectActivity activity;
|
readonly FileSelectActivity _activity;
|
||||||
FileOnFinish mFileOnFinish;
|
readonly FileOnFinish _fileOnFinish;
|
||||||
public CollectPassword(FileOnFinish finish,FileSelectActivity activity):base(finish) {
|
public CollectPassword(FileOnFinish finish,FileSelectActivity activity):base(finish) {
|
||||||
this.activity = activity;
|
_activity = activity;
|
||||||
mFileOnFinish = finish;
|
_fileOnFinish = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
SetPasswordDialog password = new SetPasswordDialog(activity, mFileOnFinish);
|
SetPasswordDialog password = new SetPasswordDialog(_activity, _fileOnFinish);
|
||||||
password.Show();
|
password.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillData() {
|
private void FillData() {
|
||||||
|
|
||||||
// Get all of the rows from the database and create the item list
|
// Get all of the rows from the database and create the item list
|
||||||
Android.Database.ICursor filesCursor = mDbHelper.fetchAllFiles();
|
Android.Database.ICursor filesCursor = _DbHelper.FetchAllFiles();
|
||||||
StartManagingCursor(filesCursor);
|
StartManagingCursor(filesCursor);
|
||||||
|
|
||||||
// Create an array to specify the fields we want to display in the list
|
// Create an array to specify the fields we want to display in the list
|
||||||
// (only TITLE)
|
// (only TITLE)
|
||||||
String[] from = new String[] { FileDbHelper.KEY_FILE_FILENAME };
|
String[] from = new[] { FileDbHelper.KeyFileFilename };
|
||||||
|
|
||||||
// and an array of the fields we want to bind those fields to (in this
|
// and an array of the fields we want to bind those fields to (in this
|
||||||
// case just text1)
|
// case just text1)
|
||||||
int[] to = new int[] { Resource.Id.file_filename };
|
int[] to = new[] { Resource.Id.file_filename };
|
||||||
|
|
||||||
// Now create a simple cursor adapter and set it to display
|
// Now create a simple cursor adapter and set it to display
|
||||||
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
|
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
|
||||||
@ -375,20 +363,20 @@ namespace keepass2android
|
|||||||
//Build dialog to query credentials:
|
//Build dialog to query credentials:
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.SetTitle(GetString(Resource.String.credentials_dialog_title));
|
builder.SetTitle(GetString(Resource.String.credentials_dialog_title));
|
||||||
builder.SetPositiveButton(GetString(Android.Resource.String.Ok), new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) =>
|
builder.SetPositiveButton(GetString(Android.Resource.String.Ok), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
Dialog dlg = (Dialog)dlgSender;
|
Dialog dlg = (Dialog)dlgSender;
|
||||||
string username = ((EditText)dlg.FindViewById(Resource.Id.cred_username)).Text;
|
string username = ((EditText)dlg.FindViewById(Resource.Id.cred_username)).Text;
|
||||||
string password = ((EditText)dlg.FindViewById(Resource.Id.cred_password)).Text;
|
string password = ((EditText)dlg.FindViewById(Resource.Id.cred_password)).Text;
|
||||||
int credentialRememberMode = ((Spinner)dlg.FindViewById(Resource.Id.cred_remember_mode)).SelectedItemPosition;
|
int credentialRememberMode = ((Spinner)dlg.FindViewById(Resource.Id.cred_remember_mode)).SelectedItemPosition;
|
||||||
ioc.UserName = username;
|
ioc.UserName = username;
|
||||||
ioc.Password = password;
|
ioc.Password = password;
|
||||||
ioc.CredSaveMode = (IOCredSaveMode)credentialRememberMode;
|
ioc.CredSaveMode = (IOCredSaveMode)credentialRememberMode;
|
||||||
PasswordActivity.Launch(this, ioc, mAppTask);
|
PasswordActivity.Launch(this, ioc, AppTask);
|
||||||
}));
|
});
|
||||||
builder.SetView(LayoutInflater.Inflate(Resource.Layout.url_credentials, null));
|
builder.SetView(LayoutInflater.Inflate(Resource.Layout.url_credentials, null));
|
||||||
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
builder.SetNeutralButton(GetString(Android.Resource.String.Cancel),
|
||||||
new EventHandler<DialogClickEventArgs>((dlgSender, dlgEvt) => {}));
|
(dlgSender, dlgEvt) => {});
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
((EditText)dialog.FindViewById(Resource.Id.cred_username)).Text = ioc.UserName;
|
((EditText)dialog.FindViewById(Resource.Id.cred_username)).Text = ioc.UserName;
|
||||||
@ -399,7 +387,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this, ioc, mAppTask);
|
PasswordActivity.Launch(this, ioc, AppTask);
|
||||||
} catch (Java.IO.FileNotFoundException)
|
} catch (Java.IO.FileNotFoundException)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
|
||||||
@ -410,10 +398,10 @@ namespace keepass2android
|
|||||||
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||||
base.OnListItemClick(l, v, position, id);
|
base.OnListItemClick(l, v, position, id);
|
||||||
|
|
||||||
Android.Database.ICursor cursor = mDbHelper.fetchFile(id);
|
Android.Database.ICursor cursor = _DbHelper.FetchFile(id);
|
||||||
StartManagingCursor(cursor);
|
StartManagingCursor(cursor);
|
||||||
|
|
||||||
IOConnectionInfo ioc = mDbHelper.cursorToIoc(cursor);
|
IOConnectionInfo ioc = _DbHelper.CursorToIoc(cursor);
|
||||||
|
|
||||||
LaunchPasswordActivityForIoc(ioc);
|
LaunchPasswordActivityForIoc(ioc);
|
||||||
|
|
||||||
@ -425,18 +413,18 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
createdWithActivityResult = true;
|
_createdWithActivityResult = true;
|
||||||
|
|
||||||
if (resultCode == KeePass.EXIT_CLOSE_AFTER_TASK_COMPLETE)
|
if (resultCode == KeePass.ExitCloseAfterTaskComplete)
|
||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fillData();
|
FillData();
|
||||||
|
|
||||||
if ( (requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_CREATE
|
if ( (requestCode == Intents.RequestCodeFileBrowseForCreate
|
||||||
|| requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_OPEN)
|
|| requestCode == Intents.RequestCodeFileBrowseForOpen)
|
||||||
&& resultCode == Result.Ok) {
|
&& resultCode == Result.Ok) {
|
||||||
string filename = Util.IntentToFilename(data);
|
string filename = Util.IntentToFilename(data);
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
@ -446,18 +434,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
filename = Java.Net.URLDecoder.Decode(filename);
|
filename = Java.Net.URLDecoder.Decode(filename);
|
||||||
|
|
||||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_OPEN)
|
if (requestCode == Intents.RequestCodeFileBrowseForOpen)
|
||||||
{
|
{
|
||||||
IOConnectionInfo ioc = new IOConnectionInfo() {
|
IOConnectionInfo ioc = new IOConnectionInfo
|
||||||
|
{
|
||||||
Path = filename
|
Path = filename
|
||||||
};
|
};
|
||||||
|
|
||||||
LaunchPasswordActivityForIoc(ioc);
|
LaunchPasswordActivityForIoc(ioc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE_FOR_CREATE)
|
if (requestCode == Intents.RequestCodeFileBrowseForCreate)
|
||||||
{
|
{
|
||||||
ShowFilenameDialog(false, true, true, filename, "", Intents.REQUEST_CODE_FILE_BROWSE_FOR_CREATE);
|
ShowFilenameDialog(false, true, true, filename, "", Intents.RequestCodeFileBrowseForCreate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,28 +460,28 @@ namespace keepass2android
|
|||||||
Android.Util.Log.Debug("DEBUG", "FileSelect.OnResume");
|
Android.Util.Log.Debug("DEBUG", "FileSelect.OnResume");
|
||||||
|
|
||||||
// Check to see if we need to change modes
|
// Check to see if we need to change modes
|
||||||
if (mDbHelper.hasRecentFiles() != recentMode)
|
if (_DbHelper.HasRecentFiles() != _recentMode)
|
||||||
{
|
{
|
||||||
// Restart the activity
|
// Restart the activity
|
||||||
Intent intent = this.Intent;
|
Intent intent = Intent;
|
||||||
StartActivity(intent);
|
StartActivity(intent);
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fileSelectButtons.updateExternalStorageWarning();
|
_fileSelectButtons.UpdateExternalStorageWarning();
|
||||||
|
|
||||||
if (!createdWithActivityResult)
|
if (!_createdWithActivityResult)
|
||||||
{
|
{
|
||||||
if ((Intent.Action == Intent.ActionSend) && (App.getDB().Loaded))
|
if ((Intent.Action == Intent.ActionSend) && (App.Kp2a.GetDb().Loaded))
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this, App.getDB().mIoc , mAppTask);
|
PasswordActivity.Launch(this, App.Kp2a.GetDb().Ioc , AppTask);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Load default database
|
// Load default database
|
||||||
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(this);
|
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
String defaultFileName = prefs.GetString(PasswordActivity.KEY_DEFAULT_FILENAME, "");
|
String defaultFileName = prefs.GetString(PasswordActivity.KeyDefaultFilename, "");
|
||||||
|
|
||||||
if (defaultFileName.Length > 0)
|
if (defaultFileName.Length > 0)
|
||||||
{
|
{
|
||||||
@ -502,7 +491,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PasswordActivity.Launch(this, loadIoc(defaultFileName), mAppTask);
|
PasswordActivity.Launch(this, LoadIoc(defaultFileName), AppTask);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Toast.MakeText(this, e.Message, ToastLength.Long);
|
Toast.MakeText(this, e.Message, ToastLength.Long);
|
||||||
@ -520,7 +509,7 @@ namespace keepass2android
|
|||||||
base.OnStart();
|
base.OnStart();
|
||||||
Android.Util.Log.Debug("DEBUG", "FileSelect.OnStart");
|
Android.Util.Log.Debug("DEBUG", "FileSelect.OnStart");
|
||||||
}
|
}
|
||||||
public override bool OnCreateOptionsMenu(Android.Views.IMenu menu) {
|
public override bool OnCreateOptionsMenu(IMenu menu) {
|
||||||
base.OnCreateOptionsMenu(menu);
|
base.OnCreateOptionsMenu(menu);
|
||||||
|
|
||||||
MenuInflater inflater = MenuInflater;
|
MenuInflater inflater = MenuInflater;
|
||||||
@ -548,7 +537,7 @@ namespace keepass2android
|
|||||||
Android.Util.Log.Debug("DEBUG", "FileSelect.OnStop");
|
Android.Util.Log.Debug("DEBUG", "FileSelect.OnStop");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnOptionsItemSelected(Android.Views.IMenuItem item) {
|
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||||
switch (item.ItemId) {
|
switch (item.ItemId) {
|
||||||
case Resource.Id.menu_donate:
|
case Resource.Id.menu_donate:
|
||||||
try {
|
try {
|
||||||
@ -573,24 +562,24 @@ namespace keepass2android
|
|||||||
return base.OnOptionsItemSelected(item);
|
return base.OnOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCreateContextMenu(Android.Views.IContextMenu menu, View v,
|
public override void OnCreateContextMenu(IContextMenu menu, View v,
|
||||||
Android.Views.IContextMenuContextMenuInfo menuInfo) {
|
IContextMenuContextMenuInfo menuInfo) {
|
||||||
base.OnCreateContextMenu(menu, v, menuInfo);
|
base.OnCreateContextMenu(menu, v, menuInfo);
|
||||||
|
|
||||||
menu.Add(0, CMENU_CLEAR, 0, Resource.String.remove_from_filelist);
|
menu.Add(0, CmenuClear, 0, Resource.String.remove_from_filelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnContextItemSelected(Android.Views.IMenuItem item) {
|
public override bool OnContextItemSelected(IMenuItem item) {
|
||||||
base.OnContextItemSelected(item);
|
base.OnContextItemSelected(item);
|
||||||
|
|
||||||
if ( item.ItemId == CMENU_CLEAR ) {
|
if ( item.ItemId == CmenuClear ) {
|
||||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) item.MenuInfo;
|
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) item.MenuInfo;
|
||||||
|
|
||||||
TextView tv = (TextView) acmi.TargetView;
|
TextView tv = (TextView) acmi.TargetView;
|
||||||
String filename = tv.Text;
|
String filename = tv.Text;
|
||||||
mDbHelper.deleteFile(filename);
|
_DbHelper.DeleteFile(filename);
|
||||||
|
|
||||||
refreshList();
|
RefreshList();
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -599,7 +588,7 @@ namespace keepass2android
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshList() {
|
private void RefreshList() {
|
||||||
CursorAdapter ca = (CursorAdapter) ListAdapter;
|
CursorAdapter ca = (CursorAdapter) ListAdapter;
|
||||||
Android.Database.ICursor cursor = ca.Cursor;
|
Android.Database.ICursor cursor = ca.Cursor;
|
||||||
cursor.Requery();
|
cursor.Requery();
|
||||||
|
@ -15,16 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
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 Android.Widget;
|
||||||
using Android.Graphics.Drawables;
|
using Android.Graphics.Drawables;
|
||||||
using Android.Content.Res;
|
using Android.Content.Res;
|
||||||
@ -33,82 +24,84 @@ using Android.Graphics;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
public class DrawableFactory
|
/// <summary>
|
||||||
|
/// Factory to create password icons
|
||||||
|
/// </summary>
|
||||||
|
public class DrawableFactory: IDrawableFactory
|
||||||
{
|
{
|
||||||
private static Drawable blank = null;
|
private static Drawable _blank;
|
||||||
private static int blankWidth = -1;
|
private static int _blankWidth = -1;
|
||||||
private static int blankHeight = -1;
|
private static int _blankHeight = -1;
|
||||||
|
|
||||||
/** customIconMap
|
/** customIconMap
|
||||||
* Cache for icon drawable.
|
* Cache for icon drawable.
|
||||||
* Keys: UUID, Values: Drawables
|
* Keys: UUID, Values: Drawables
|
||||||
*/
|
*/
|
||||||
private Dictionary<PwUuid, Drawable> customIconMap = new Dictionary<PwUuid, Drawable>(new PwUuidEqualityComparer());
|
private readonly Dictionary<PwUuid, Drawable> _customIconMap = new Dictionary<PwUuid, Drawable>(new PwUuidEqualityComparer());
|
||||||
|
|
||||||
/** standardIconMap
|
/** standardIconMap
|
||||||
* Cache for icon drawable.
|
* Cache for icon drawable.
|
||||||
* Keys: Integer, Values: Drawables
|
* Keys: Integer, Values: Drawables
|
||||||
*/
|
*/
|
||||||
private Dictionary<int/*resId*/, Drawable> standardIconMap = new Dictionary<int, Drawable>();
|
private readonly Dictionary<int/*resId*/, Drawable> _standardIconMap = new Dictionary<int, Drawable>();
|
||||||
|
|
||||||
public void assignDrawableTo (ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
public void AssignDrawableTo (ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
||||||
{
|
{
|
||||||
Drawable draw = getIconDrawable (res, db, icon, customIconId);
|
Drawable draw = GetIconDrawable (res, db, icon, customIconId);
|
||||||
iv.SetImageDrawable (draw);
|
iv.SetImageDrawable (draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable getIconDrawable (Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
public Drawable GetIconDrawable (Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId)
|
||||||
{
|
{
|
||||||
if (!customIconId.EqualsValue(PwUuid.Zero)) {
|
if (!customIconId.EqualsValue(PwUuid.Zero)) {
|
||||||
return getIconDrawable (res, db, customIconId);
|
return GetIconDrawable (res, db, customIconId);
|
||||||
} else {
|
|
||||||
return getIconDrawable (res, icon);
|
|
||||||
}
|
}
|
||||||
|
return GetIconDrawable (res, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initBlank (Resources res)
|
private static void InitBlank (Resources res)
|
||||||
{
|
{
|
||||||
if (blank == null) {
|
if (_blank == null) {
|
||||||
blank = res.GetDrawable (Resource.Drawable.ic99_blank);
|
_blank = res.GetDrawable (Resource.Drawable.ic99_blank);
|
||||||
blankWidth = blank.IntrinsicWidth;
|
_blankWidth = _blank.IntrinsicWidth;
|
||||||
blankHeight = blank.IntrinsicHeight;
|
_blankHeight = _blank.IntrinsicHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable getIconDrawable (Resources res, PwIcon icon)
|
public Drawable GetIconDrawable (Resources res, PwIcon icon)
|
||||||
{
|
{
|
||||||
int resId = Icons.iconToResId (icon);
|
int resId = Icons.IconToResId (icon);
|
||||||
|
|
||||||
Drawable draw;
|
Drawable draw;
|
||||||
if (!standardIconMap.TryGetValue(resId, out draw))
|
if (!_standardIconMap.TryGetValue(resId, out draw))
|
||||||
{
|
{
|
||||||
draw = res.GetDrawable(resId);
|
draw = res.GetDrawable(resId);
|
||||||
standardIconMap[resId] = draw;
|
_standardIconMap[resId] = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return draw;
|
return draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable getIconDrawable (Resources res, PwDatabase db, PwUuid icon)
|
public Drawable GetIconDrawable (Resources res, PwDatabase db, PwUuid icon)
|
||||||
{
|
{
|
||||||
initBlank (res);
|
InitBlank (res);
|
||||||
if (icon.EqualsValue(PwUuid.Zero)) {
|
if (icon.EqualsValue(PwUuid.Zero)) {
|
||||||
return blank;
|
return _blank;
|
||||||
}
|
}
|
||||||
Drawable draw = null;
|
Drawable draw;
|
||||||
if (!customIconMap.TryGetValue(icon, out draw))
|
if (!_customIconMap.TryGetValue(icon, out draw))
|
||||||
{
|
{
|
||||||
Bitmap bitmap = db.GetCustomIcon(icon);
|
Bitmap bitmap = db.GetCustomIcon(icon);
|
||||||
|
|
||||||
// Could not understand custom icon
|
// Could not understand custom icon
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
return blank;
|
return _blank;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap = resize (bitmap);
|
bitmap = resize (bitmap);
|
||||||
|
|
||||||
draw = BitmapDrawableCompat.getBitmapDrawable (res, bitmap);
|
draw = new BitmapDrawable(res, bitmap);
|
||||||
customIconMap[icon] = draw;
|
_customIconMap[icon] = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return draw;
|
return draw;
|
||||||
@ -123,17 +116,17 @@ namespace keepass2android
|
|||||||
int width = bitmap.Width;
|
int width = bitmap.Width;
|
||||||
int height = bitmap.Height;
|
int height = bitmap.Height;
|
||||||
|
|
||||||
if (width == blankWidth && height == blankHeight) {
|
if (width == _blankWidth && height == _blankHeight) {
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Bitmap.CreateScaledBitmap (bitmap, blankWidth, blankHeight, true);
|
return Bitmap.CreateScaledBitmap (bitmap, _blankWidth, _blankHeight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear ()
|
public void Clear ()
|
||||||
{
|
{
|
||||||
standardIconMap.Clear ();
|
_standardIconMap.Clear ();
|
||||||
customIconMap.Clear ();
|
_customIconMap.Clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,68 +17,69 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
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 System.Reflection;
|
using System.Reflection;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using Android.Util;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
public class Icons {
|
/// Stores the default pw entry icons
|
||||||
private static Dictionary<PwIcon,int> icons = null;
|
/// </summary>
|
||||||
|
public class Icons
|
||||||
private static void buildList() {
|
{
|
||||||
if (icons == null) {
|
private static Dictionary<PwIcon, int> _icons;
|
||||||
icons = new Dictionary<PwIcon,int>();
|
|
||||||
|
|
||||||
FieldInfo[] fields = typeof(Resource.Drawable).GetFields(BindingFlags.Static | BindingFlags.Public);
|
private static void BuildList()
|
||||||
for (int i = 0; i < fields.Length; i++) {
|
{
|
||||||
String fieldName = fields[i].Name;
|
if (_icons != null) return;
|
||||||
|
|
||||||
if (fieldName.StartsWith("ic") && (fieldName.Length >= 4))
|
_icons = new Dictionary<PwIcon, int>();
|
||||||
|
|
||||||
|
FieldInfo[] fields = typeof(Resource.Drawable).GetFields(BindingFlags.Static | BindingFlags.Public);
|
||||||
|
foreach (FieldInfo fieldInfo in fields)
|
||||||
|
{
|
||||||
|
String fieldName = fieldInfo.Name;
|
||||||
|
|
||||||
|
if (fieldName.StartsWith("ic") && (fieldName.Length >= 4))
|
||||||
|
{
|
||||||
|
|
||||||
|
String sNum = fieldName.Substring(2, 2);
|
||||||
|
int num;
|
||||||
|
if (int.TryParse(sNum, out num) && (num < (int)PwIcon.Count))
|
||||||
{
|
{
|
||||||
|
|
||||||
String sNum = fieldName.Substring(2, 2);
|
|
||||||
int num;
|
|
||||||
if (int.TryParse(sNum,out num) && (num < (int)PwIcon.Count))
|
|
||||||
{
|
|
||||||
|
|
||||||
int resId;
|
int resId;
|
||||||
try {
|
try
|
||||||
resId = (int)fields[i].GetValue(null);
|
{
|
||||||
} catch (Exception) {
|
resId = (int)fieldInfo.GetValue(null);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
icons[(PwIcon)num] = resId;
|
_icons[(PwIcon)num] = resId;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int iconToResId(PwIcon iconId) {
|
public static int IconToResId(PwIcon iconId)
|
||||||
buildList();
|
{
|
||||||
int resId = Resource.Drawable.ic99_blank;
|
BuildList();
|
||||||
icons.TryGetValue(iconId, out resId);
|
int resId;
|
||||||
return resId;
|
if (_icons.TryGetValue(iconId, out resId))
|
||||||
|
return resId;
|
||||||
|
return Resource.Drawable.ic99_blank;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int count() {
|
public static int Count()
|
||||||
buildList();
|
{
|
||||||
|
BuildList();
|
||||||
return icons.Count;
|
|
||||||
|
return _icons.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,34 +16,26 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
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;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains constants to be used in intents
|
||||||
|
/// </summary>
|
||||||
public class Intents {
|
public class Intents {
|
||||||
public const String TIMEOUT = "keepass2android.timeout";
|
public const String Timeout = "keepass2android.timeout";
|
||||||
|
|
||||||
public const String COPY_USERNAME = "keepass2android.copy_username";
|
public const String CopyUsername = "keepass2android.copy_username";
|
||||||
public const String COPY_PASSWORD = "keepass2android.copy_password";
|
public const String CopyPassword = "keepass2android.copy_password";
|
||||||
public const String CHECK_KEYBOARD = "keepass2android.check_keyboard";
|
public const String CheckKeyboard = "keepass2android.check_keyboard";
|
||||||
|
|
||||||
public const String FILE_BROWSE = "org.openintents.action.PICK_FILE";
|
public const String FileBrowse = "org.openintents.action.PICK_FILE";
|
||||||
public const int REQUEST_CODE_FILE_BROWSE_FOR_OPEN = 987321;
|
public const int RequestCodeFileBrowseForOpen = 987321;
|
||||||
public const int REQUEST_CODE_FILE_BROWSE_FOR_CREATE = 987322;
|
public const int RequestCodeFileBrowseForCreate = 987322;
|
||||||
public const int REQUEST_CODE_FILE_BROWSE_FOR_BINARY = 987323;
|
public const int RequestCodeFileBrowseForBinary = 987323;
|
||||||
public const int REQUEST_CODE_FILE_BROWSE_FOR_KEYFILE = 987324;
|
public const int RequestCodeFileBrowseForKeyfile = 987324;
|
||||||
|
|
||||||
public const String SHOW_NOTIFICATION = "keepass2android.show_notification";
|
public const String ShowNotification = "keepass2android.show_notification";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@ -77,28 +77,19 @@
|
|||||||
<Reference Include="Mono.Android.Support.v4" />
|
<Reference Include="Mono.Android.Support.v4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="icons\DrawableFactory.cs" />
|
||||||
|
<Compile Include="icons\Icons.cs" />
|
||||||
<Compile Include="Resources\Resource.designer.cs" />
|
<Compile Include="Resources\Resource.designer.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="KeePass.cs" />
|
<Compile Include="KeePass.cs" />
|
||||||
<Compile Include="database\edit\OnFinish.cs" />
|
|
||||||
<Compile Include="database\edit\FileOnFinish.cs" />
|
|
||||||
<Compile Include="app\App.cs" />
|
<Compile Include="app\App.cs" />
|
||||||
<Compile Include="Database.cs" />
|
|
||||||
<Compile Include="fileselect\FileSelectActivity.cs" />
|
<Compile Include="fileselect\FileSelectActivity.cs" />
|
||||||
<Compile Include="fileselect\FileDbHelper.cs" />
|
<Compile Include="fileselect\FileDbHelper.cs" />
|
||||||
<Compile Include="search\SearchProvider.cs" />
|
<Compile Include="search\SearchProvider.cs" />
|
||||||
<Compile Include="Utils\Util.cs" />
|
<Compile Include="Utils\Util.cs" />
|
||||||
<Compile Include="Utils\Interaction.cs" />
|
|
||||||
<Compile Include="intents\Intents.cs" />
|
<Compile Include="intents\Intents.cs" />
|
||||||
<Compile Include="fileselect\BrowserDialog.cs" />
|
<Compile Include="fileselect\BrowserDialog.cs" />
|
||||||
<Compile Include="timeout\TimeoutHelper.cs" />
|
<Compile Include="timeout\TimeoutHelper.cs" />
|
||||||
<Compile Include="timers\Timeout.cs" />
|
|
||||||
<Compile Include="database\edit\LoadDB.cs" />
|
|
||||||
<Compile Include="database\edit\RunnableOnFinish.cs" />
|
|
||||||
<Compile Include="UpdateStatus.cs" />
|
|
||||||
<Compile Include="ProgressTask.cs" />
|
|
||||||
<Compile Include="icons\DrawableFactory.cs" />
|
|
||||||
<Compile Include="search\SearchDbHelper.cs" />
|
|
||||||
<Compile Include="GroupActivity.cs" />
|
<Compile Include="GroupActivity.cs" />
|
||||||
<Compile Include="GroupBaseActivity.cs" />
|
<Compile Include="GroupBaseActivity.cs" />
|
||||||
<Compile Include="LockCloseListActivity.cs" />
|
<Compile Include="LockCloseListActivity.cs" />
|
||||||
@ -112,16 +103,9 @@
|
|||||||
<Compile Include="settings\PrefsUtil.cs" />
|
<Compile Include="settings\PrefsUtil.cs" />
|
||||||
<Compile Include="views\PwEntryView.cs" />
|
<Compile Include="views\PwEntryView.cs" />
|
||||||
<Compile Include="views\GroupHeaderView.cs" />
|
<Compile Include="views\GroupHeaderView.cs" />
|
||||||
<Compile Include="PwUuidEqualityComparer.cs" />
|
|
||||||
<Compile Include="icons\Icons.cs" />
|
|
||||||
<Compile Include="BitmapDrawableCompat.cs" />
|
|
||||||
<Compile Include="GroupEditActivity.cs" />
|
<Compile Include="GroupEditActivity.cs" />
|
||||||
<Compile Include="database\edit\AddGroup.cs" />
|
|
||||||
<Compile Include="database\edit\SaveDB.cs" />
|
|
||||||
<Compile Include="EntryEditActivity.cs" />
|
<Compile Include="EntryEditActivity.cs" />
|
||||||
<Compile Include="LockCloseActivity.cs" />
|
<Compile Include="LockCloseActivity.cs" />
|
||||||
<Compile Include="database\edit\AddEntry.cs" />
|
|
||||||
<Compile Include="database\edit\UpdateEntry.cs" />
|
|
||||||
<Compile Include="EntryActivity.cs" />
|
<Compile Include="EntryActivity.cs" />
|
||||||
<Compile Include="GeneratePasswordActivity.cs" />
|
<Compile Include="GeneratePasswordActivity.cs" />
|
||||||
<Compile Include="password\PasswordGenerator.cs" />
|
<Compile Include="password\PasswordGenerator.cs" />
|
||||||
@ -135,20 +119,13 @@
|
|||||||
<Compile Include="LockingPreferenceActivity.cs" />
|
<Compile Include="LockingPreferenceActivity.cs" />
|
||||||
<Compile Include="SetPasswordDialog.cs" />
|
<Compile Include="SetPasswordDialog.cs" />
|
||||||
<Compile Include="CancelDialog.cs" />
|
<Compile Include="CancelDialog.cs" />
|
||||||
<Compile Include="database\edit\SetPassword.cs" />
|
|
||||||
<Compile Include="database\edit\CreateDB.cs" />
|
|
||||||
<Compile Include="AboutDialog.cs" />
|
<Compile Include="AboutDialog.cs" />
|
||||||
<Compile Include="settings\AppSettingsActivity.cs" />
|
<Compile Include="settings\AppSettingsActivity.cs" />
|
||||||
<Compile Include="settings\RoundsPreference.cs" />
|
<Compile Include="settings\RoundsPreference.cs" />
|
||||||
<Compile Include="KeyFileException.cs" />
|
|
||||||
<Compile Include="PasswordActivity.cs" />
|
<Compile Include="PasswordActivity.cs" />
|
||||||
<Compile Include="database\edit\DeleteGroup.cs" />
|
|
||||||
<Compile Include="PwGroupEqualityFromIdComparer.cs" />
|
|
||||||
<Compile Include="database\edit\DeleteEntry.cs" />
|
|
||||||
<Compile Include="search\SearchResults.cs" />
|
<Compile Include="search\SearchResults.cs" />
|
||||||
<Compile Include="compat\EditorCompat.cs" />
|
<Compile Include="compat\EditorCompat.cs" />
|
||||||
<Compile Include="compat\ActivityCompat.cs" />
|
<Compile Include="compat\ActivityCompat.cs" />
|
||||||
<Compile Include="database\edit\ActionOnFinish.cs" />
|
|
||||||
<Compile Include="ShareUrlResults.cs" />
|
<Compile Include="ShareUrlResults.cs" />
|
||||||
<Compile Include="services\TimeoutService.cs" />
|
<Compile Include="services\TimeoutService.cs" />
|
||||||
<Compile Include="services\CopyToClipboardService.cs" />
|
<Compile Include="services\CopyToClipboardService.cs" />
|
||||||
@ -158,7 +135,6 @@
|
|||||||
<Compile Include="LifecycleDebugActivity.cs" />
|
<Compile Include="LifecycleDebugActivity.cs" />
|
||||||
<Compile Include="services\QuickUnlockForegroundService.cs" />
|
<Compile Include="services\QuickUnlockForegroundService.cs" />
|
||||||
<Compile Include="AssemblyInfo.cs" />
|
<Compile Include="AssemblyInfo.cs" />
|
||||||
<Compile Include="database\edit\DeleteRunnable.cs" />
|
|
||||||
<Compile Include="views\FileSelectButtons.cs" />
|
<Compile Include="views\FileSelectButtons.cs" />
|
||||||
<Compile Include="EntryEditActivityState.cs" />
|
<Compile Include="EntryEditActivityState.cs" />
|
||||||
<Compile Include="AttachmentContentProvider.cs" />
|
<Compile Include="AttachmentContentProvider.cs" />
|
||||||
@ -658,62 +634,17 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="database\" />
|
|
||||||
<Folder Include="database\edit\" />
|
|
||||||
<Folder Include="app\" />
|
|
||||||
<Folder Include="fileselect\" />
|
|
||||||
<Folder Include="Utils\" />
|
|
||||||
<Folder Include="intents\" />
|
|
||||||
<Folder Include="views\" />
|
|
||||||
<Folder Include="timeout\" />
|
|
||||||
<Folder Include="timers\" />
|
|
||||||
<Folder Include="services\" />
|
|
||||||
<Folder Include="icons\" />
|
|
||||||
<Folder Include="search\" />
|
|
||||||
<Folder Include="settings\" />
|
|
||||||
<Folder Include="password\" />
|
|
||||||
<Folder Include="compat\" />
|
|
||||||
<Folder Include="Resources\menu-v11\" />
|
|
||||||
<Folder Include="Resources\drawable-hdpi\" />
|
|
||||||
<Folder Include="Resources\drawable-ldpi\" />
|
|
||||||
<Folder Include="Resources\drawable-mdpi\" />
|
|
||||||
<Folder Include="Resources\drawable-xhdpi\" />
|
|
||||||
<Folder Include="Resources\drawable-xxhdpi\" />
|
|
||||||
<Folder Include="Resources\drawable-v11\" />
|
|
||||||
<Folder Include="Resources\values-de\" />
|
|
||||||
<Folder Include="Resources\values-ca\" />
|
|
||||||
<Folder Include="Resources\values-cs\" />
|
|
||||||
<Folder Include="Resources\values-da\" />
|
|
||||||
<Folder Include="Resources\values-es\" />
|
|
||||||
<Folder Include="Resources\values-fr\" />
|
|
||||||
<Folder Include="Resources\values-hu\" />
|
|
||||||
<Folder Include="Resources\values-it\" />
|
|
||||||
<Folder Include="Resources\values-ja\" />
|
|
||||||
<Folder Include="Resources\values-nl\" />
|
|
||||||
<Folder Include="Resources\values-nn\" />
|
|
||||||
<Folder Include="Resources\values-pl\" />
|
|
||||||
<Folder Include="Resources\values-pt-rBR\" />
|
|
||||||
<Folder Include="Resources\values-ru\" />
|
|
||||||
<Folder Include="Resources\values-sk\" />
|
|
||||||
<Folder Include="Resources\values-uk\" />
|
|
||||||
<Folder Include="Resources\values-zh-rCN\" />
|
|
||||||
<Folder Include="Resources\values-zh-rTW\" />
|
|
||||||
<Folder Include="SupportLib\" />
|
|
||||||
<Folder Include="Assets\" />
|
<Folder Include="Assets\" />
|
||||||
<Folder Include="libs\" />
|
|
||||||
<Folder Include="libs\armeabi-v7a\" />
|
|
||||||
<Folder Include="libs\armeabi\" />
|
|
||||||
<Folder Include="libs\mips\" />
|
|
||||||
<Folder Include="Resources\values-v14\" />
|
|
||||||
<Folder Include="Resources\layout-v14\" />
|
|
||||||
<Folder Include="Resources\anim\" />
|
|
||||||
<Folder Include="Utils\Spr\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
|
||||||
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
|
||||||
<Name>KeePassLib2Android</Name>
|
<Name>KeePassLib2Android</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
|
||||||
|
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
|
||||||
|
<Name>Kp2aBusinessLogic</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj">
|
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj">
|
||||||
<Project>{A57B3ACE-5634-469A-88C4-858BB409F356}</Project>
|
<Project>{A57B3ACE-5634-469A-88C4-858BB409F356}</Project>
|
||||||
<Name>kp2akeytransform</Name>
|
<Name>kp2akeytransform</Name>
|
||||||
|
@ -16,44 +16,38 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Password generator
|
||||||
|
/// </summary>
|
||||||
public class PasswordGenerator {
|
public class PasswordGenerator {
|
||||||
private const String upperCaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
private const String UpperCaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
private const String lowerCaseChars = "abcdefghijklmnopqrstuvwxyz";
|
private const String LowerCaseChars = "abcdefghijklmnopqrstuvwxyz";
|
||||||
private const String digitChars = "0123456789";
|
private const String DigitChars = "0123456789";
|
||||||
private const String minusChars = "-";
|
private const String MinusChars = "-";
|
||||||
private const String underlineChars = "_";
|
private const String UnderlineChars = "_";
|
||||||
private const String spaceChars = " ";
|
private const String SpaceChars = " ";
|
||||||
private const String specialChars = "!\"#$%&'*+,./:;=?@\\^`";
|
private const String SpecialChars = "!\"#$%&'*+,./:;=?@\\^`";
|
||||||
private const String bracketChars = "[]{}()<>";
|
private const String BracketChars = "[]{}()<>";
|
||||||
|
|
||||||
private Context cxt;
|
private readonly Context _cxt;
|
||||||
|
|
||||||
public PasswordGenerator(Context cxt) {
|
public PasswordGenerator(Context cxt) {
|
||||||
this.cxt = cxt;
|
_cxt = cxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generatePassword(int length, bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
public String GeneratePassword(int length, bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
throw new ArgumentException(cxt.GetString(Resource.String.error_wrong_length));
|
throw new ArgumentException(_cxt.GetString(Resource.String.error_wrong_length));
|
||||||
|
|
||||||
if (!upperCase && !lowerCase && !digits && !minus && !underline && !space && !specials && !brackets)
|
if (!upperCase && !lowerCase && !digits && !minus && !underline && !space && !specials && !brackets)
|
||||||
throw new ArgumentException(cxt.GetString(Resource.String.error_pass_gen_type));
|
throw new ArgumentException(_cxt.GetString(Resource.String.error_pass_gen_type));
|
||||||
|
|
||||||
String characterSet = getCharacterSet(upperCase, lowerCase, digits, minus, underline, space, specials, brackets);
|
String characterSet = GetCharacterSet(upperCase, lowerCase, digits, minus, underline, space, specials, brackets);
|
||||||
|
|
||||||
int size = characterSet.Length;
|
int size = characterSet.Length;
|
||||||
|
|
||||||
@ -72,32 +66,32 @@ namespace keepass2android
|
|||||||
return buffer.ToString();
|
return buffer.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCharacterSet(bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
public String GetCharacterSet(bool upperCase, bool lowerCase, bool digits, bool minus, bool underline, bool space, bool specials, bool brackets) {
|
||||||
StringBuilder charSet = new StringBuilder();
|
StringBuilder charSet = new StringBuilder();
|
||||||
|
|
||||||
if (upperCase)
|
if (upperCase)
|
||||||
charSet.Append(upperCaseChars);
|
charSet.Append(UpperCaseChars);
|
||||||
|
|
||||||
if (lowerCase)
|
if (lowerCase)
|
||||||
charSet.Append(lowerCaseChars);
|
charSet.Append(LowerCaseChars);
|
||||||
|
|
||||||
if (digits)
|
if (digits)
|
||||||
charSet.Append(digitChars);
|
charSet.Append(DigitChars);
|
||||||
|
|
||||||
if (minus)
|
if (minus)
|
||||||
charSet.Append(minusChars);
|
charSet.Append(MinusChars);
|
||||||
|
|
||||||
if (underline)
|
if (underline)
|
||||||
charSet.Append(underlineChars);
|
charSet.Append(UnderlineChars);
|
||||||
|
|
||||||
if (space)
|
if (space)
|
||||||
charSet.Append(spaceChars);
|
charSet.Append(SpaceChars);
|
||||||
|
|
||||||
if (specials)
|
if (specials)
|
||||||
charSet.Append(specialChars);
|
charSet.Append(SpecialChars);
|
||||||
|
|
||||||
if (brackets)
|
if (brackets)
|
||||||
charSet.Append(bracketChars);
|
charSet.Append(BracketChars);
|
||||||
|
|
||||||
return charSet.ToString();
|
return charSet.ToString();
|
||||||
}
|
}
|
||||||
|
@ -16,21 +16,18 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using keepass2android.search;
|
using keepass2android.search;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Activity to display search options
|
||||||
|
/// </summary>
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/Base")]
|
[Activity (Label = "@string/app_name", Theme="@style/Base")]
|
||||||
public class SearchActivity : LifecycleDebugActivity
|
public class SearchActivity : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
@ -44,38 +41,35 @@ namespace keepass2android
|
|||||||
base.OnCreate(bundle);
|
base.OnCreate(bundle);
|
||||||
SetContentView(Resource.Layout.search);
|
SetContentView(Resource.Layout.search);
|
||||||
SearchParameters sp = new SearchParameters();
|
SearchParameters sp = new SearchParameters();
|
||||||
populateCheckBox(Resource.Id.cbSearchInTitle, sp.SearchInTitles);
|
PopulateCheckBox(Resource.Id.cbSearchInTitle, sp.SearchInTitles);
|
||||||
populateCheckBox(Resource.Id.cbSearchInUsername, sp.SearchInUserNames);
|
PopulateCheckBox(Resource.Id.cbSearchInUsername, sp.SearchInUserNames);
|
||||||
populateCheckBox(Resource.Id.cbSearchInNotes, sp.SearchInNotes);
|
PopulateCheckBox(Resource.Id.cbSearchInNotes, sp.SearchInNotes);
|
||||||
populateCheckBox(Resource.Id.cbSearchInPassword, sp.SearchInPasswords);
|
PopulateCheckBox(Resource.Id.cbSearchInPassword, sp.SearchInPasswords);
|
||||||
populateCheckBox(Resource.Id.cbSearchInTags, sp.SearchInTags);
|
PopulateCheckBox(Resource.Id.cbSearchInTags, sp.SearchInTags);
|
||||||
populateCheckBox(Resource.Id.cbSearchInGroupName, sp.SearchInGroupNames);
|
PopulateCheckBox(Resource.Id.cbSearchInGroupName, sp.SearchInGroupNames);
|
||||||
populateCheckBox(Resource.Id.cbSearchInUrl, sp.SearchInUrls);
|
PopulateCheckBox(Resource.Id.cbSearchInUrl, sp.SearchInUrls);
|
||||||
populateCheckBox(Resource.Id.cbSearchInOtherStrings, sp.SearchInOther);
|
PopulateCheckBox(Resource.Id.cbSearchInOtherStrings, sp.SearchInOther);
|
||||||
populateCheckBox(Resource.Id.cbRegEx, sp.RegularExpression);
|
PopulateCheckBox(Resource.Id.cbRegEx, sp.RegularExpression);
|
||||||
|
|
||||||
StringComparison sc = sp.ComparisonMode;
|
StringComparison sc = sp.ComparisonMode;
|
||||||
bool caseSensitive = ((sc != StringComparison.CurrentCultureIgnoreCase) &&
|
bool caseSensitive = ((sc != StringComparison.CurrentCultureIgnoreCase) &&
|
||||||
(sc != StringComparison.InvariantCultureIgnoreCase) &&
|
(sc != StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
(sc != StringComparison.OrdinalIgnoreCase));
|
(sc != StringComparison.OrdinalIgnoreCase));
|
||||||
populateCheckBox(Resource.Id.cbCaseSensitive, caseSensitive);
|
PopulateCheckBox(Resource.Id.cbCaseSensitive, caseSensitive);
|
||||||
populateCheckBox(Resource.Id.cbExcludeExpiredEntries, sp.ExcludeExpired);
|
PopulateCheckBox(Resource.Id.cbExcludeExpiredEntries, sp.ExcludeExpired);
|
||||||
|
|
||||||
ImageButton btnSearch = (ImageButton)FindViewById(Resource.Id.search_button);
|
ImageButton btnSearch = (ImageButton)FindViewById(Resource.Id.search_button);
|
||||||
|
|
||||||
btnSearch.Click += (object sender, EventArgs e) =>
|
btnSearch.Click += (sender, e) => PerformSearch();
|
||||||
{
|
|
||||||
PerformSearch();
|
|
||||||
};
|
|
||||||
|
|
||||||
FindViewById<EditText>(Resource.Id.searchEditText).EditorAction += (object sender, TextView.EditorActionEventArgs e) =>
|
FindViewById<EditText>(Resource.Id.searchEditText).EditorAction += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (e.ActionId == Android.Views.InputMethods.ImeAction.Search) {
|
if (e.ActionId == Android.Views.InputMethods.ImeAction.Search) {
|
||||||
PerformSearch();
|
PerformSearch();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
void populateCheckBox(int resId, bool value)
|
void PopulateCheckBox(int resId, bool value)
|
||||||
{
|
{
|
||||||
((CheckBox) FindViewById(resId)).Checked = value;
|
((CheckBox) FindViewById(resId)).Checked = value;
|
||||||
}
|
}
|
||||||
@ -85,7 +79,6 @@ namespace keepass2android
|
|||||||
String searchString = ((EditText)FindViewById(Resource.Id.searchEditText)).Text;
|
String searchString = ((EditText)FindViewById(Resource.Id.searchEditText)).Text;
|
||||||
if (String.IsNullOrWhiteSpace(searchString))
|
if (String.IsNullOrWhiteSpace(searchString))
|
||||||
return;
|
return;
|
||||||
SearchParameters spNew = new SearchParameters();
|
|
||||||
Intent searchIntent = new Intent(this, typeof(SearchResults));
|
Intent searchIntent = new Intent(this, typeof(SearchResults));
|
||||||
searchIntent.PutExtra("SearchInTitles", GetCheckBoxValue(Resource.Id.cbSearchInTitle));
|
searchIntent.PutExtra("SearchInTitles", GetCheckBoxValue(Resource.Id.cbSearchInTitle));
|
||||||
searchIntent.PutExtra("SearchInUrls", GetCheckBoxValue(Resource.Id.cbSearchInUrl));
|
searchIntent.PutExtra("SearchInUrls", GetCheckBoxValue(Resource.Id.cbSearchInUrl));
|
||||||
|
@ -15,15 +15,10 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using keepass2android.view;
|
using keepass2android.view;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
@ -31,12 +26,15 @@ using Android.Support.V4.App;
|
|||||||
|
|
||||||
namespace keepass2android.search
|
namespace keepass2android.search
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Activity to show search results
|
||||||
|
/// </summary>
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar", LaunchMode=Android.Content.PM.LaunchMode.SingleTop)]
|
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar", LaunchMode=Android.Content.PM.LaunchMode.SingleTop)]
|
||||||
[MetaData("android.app.searchable",Resource="@xml/searchable")]
|
[MetaData("android.app.searchable",Resource="@xml/searchable")]
|
||||||
[IntentFilter(new[]{Intent.ActionSearch}, Categories=new[]{Intent.CategoryDefault})]
|
[IntentFilter(new[]{Intent.ActionSearch}, Categories=new[]{Intent.CategoryDefault})]
|
||||||
public class SearchResults : GroupBaseActivity
|
public class SearchResults : GroupBaseActivity
|
||||||
{
|
{
|
||||||
private Database mDb;
|
private Database _db;
|
||||||
|
|
||||||
protected override void OnCreate (Bundle bundle)
|
protected override void OnCreate (Bundle bundle)
|
||||||
{
|
{
|
||||||
@ -46,7 +44,7 @@ namespace keepass2android.search
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetResult(KeePass.EXIT_NORMAL);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
ProcessIntent(Intent);
|
ProcessIntent(Intent);
|
||||||
}
|
}
|
||||||
@ -58,18 +56,18 @@ namespace keepass2android.search
|
|||||||
|
|
||||||
private void ProcessIntent(Intent intent)
|
private void ProcessIntent(Intent intent)
|
||||||
{
|
{
|
||||||
mDb = App.getDB();
|
_db = App.Kp2a.GetDb();
|
||||||
|
|
||||||
|
|
||||||
// Likely the app has been killed exit the activity
|
// Likely the app has been killed exit the activity
|
||||||
if (!mDb.Open)
|
if ( ! _db.Open ) {
|
||||||
{
|
|
||||||
Finish();
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.Action == Intent.ActionView)
|
if (intent.Action == Intent.ActionView)
|
||||||
{
|
{
|
||||||
var entryIntent = new Intent(this, typeof(EntryActivity));
|
var entryIntent = new Intent(this, typeof(EntryActivity));
|
||||||
entryIntent.PutExtra(EntryActivity.KEY_ENTRY, intent.Data.LastPathSegment);
|
entryIntent.PutExtra(EntryActivity.KeyEntry, intent.Data.LastPathSegment);
|
||||||
|
|
||||||
Finish(); // Close this activity so that the entry activity is navigated to from the main activity, not this one.
|
Finish(); // Close this activity so that the entry activity is navigated to from the main activity, not this one.
|
||||||
StartActivity(entryIntent);
|
StartActivity(entryIntent);
|
||||||
@ -77,14 +75,14 @@ namespace keepass2android.search
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Action may either by ActionSearch (from search widget) or null (if called from SearchActivity directly)
|
// Action may either by ActionSearch (from search widget) or null (if called from SearchActivity directly)
|
||||||
query(getSearch(intent));
|
Query(getSearch(intent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void query (SearchParameters searchParams)
|
private void Query (SearchParameters searchParams)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
mGroup = mDb.Search (searchParams);
|
Group = _db.Search (searchParams);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Toast.MakeText(this,e.Message, ToastLength.Long).Show();
|
Toast.MakeText(this,e.Message, ToastLength.Long).Show();
|
||||||
Finish();
|
Finish();
|
||||||
@ -93,22 +91,21 @@ namespace keepass2android.search
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( mGroup == null || (mGroup.Entries.Count() < 1) ) {
|
if ( Group == null || (!Group.Entries.Any()) ) {
|
||||||
SetContentView(new GroupEmptyView(this));
|
SetContentView(new GroupEmptyView(this));
|
||||||
} else {
|
} else {
|
||||||
SetContentView(new GroupViewOnlyView(this));
|
SetContentView(new GroupViewOnlyView(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
setGroupTitle();
|
SetGroupTitle();
|
||||||
|
|
||||||
ListAdapter = new PwGroupListAdapter(this, mGroup);
|
ListAdapter = new PwGroupListAdapter(this, Group);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchParameters getSearch(Intent queryIntent) {
|
private SearchParameters getSearch(Intent queryIntent) {
|
||||||
// get and process search query here
|
// get and process search query here
|
||||||
SearchParameters sp = new SearchParameters();
|
SearchParameters sp = new SearchParameters();
|
||||||
sp.SearchString = queryIntent.GetStringExtra(SearchManager.Query);
|
sp.SearchString = queryIntent.GetStringExtra(SearchManager.Query);
|
||||||
|
|
||||||
sp.SearchInTitles = queryIntent.GetBooleanExtra("SearchInTitles", sp.SearchInTitles);
|
sp.SearchInTitles = queryIntent.GetBooleanExtra("SearchInTitles", sp.SearchInTitles);
|
||||||
sp.SearchInUrls = queryIntent.GetBooleanExtra("SearchInUrls", sp.SearchInUrls);
|
sp.SearchInUrls = queryIntent.GetBooleanExtra("SearchInUrls", sp.SearchInUrls);
|
||||||
sp.SearchInPasswords = queryIntent.GetBooleanExtra("SearchInPasswords", sp.SearchInPasswords);
|
sp.SearchInPasswords = queryIntent.GetBooleanExtra("SearchInPasswords", sp.SearchInPasswords);
|
||||||
@ -134,11 +131,9 @@ namespace keepass2android.search
|
|||||||
{
|
{
|
||||||
Finish();
|
Finish();
|
||||||
return true;
|
return true;
|
||||||
} else
|
}
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,14 +18,12 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Java.Util;
|
using Java.Util;
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
@ -35,15 +33,21 @@ using KeePass.Util.Spr;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service to show the notifications to make the current entry accessible through clipboard or the KP2A keyboard.
|
||||||
|
/// </summary>
|
||||||
|
/// The name reflects only the possibility through clipboard because keyboard was introduced later.
|
||||||
|
/// The notifications require to be displayed by a service in order to be kept when the activity is closed
|
||||||
|
/// after searching for a URL.
|
||||||
[Service]
|
[Service]
|
||||||
public class CopyToClipboardService: Service
|
public class CopyToClipboardService: Service
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public const int NOTIFY_USERNAME = 1;
|
public const int NotifyUsername = 1;
|
||||||
public const int NOTIFY_PASSWORD = 2;
|
public const int NotifyPassword = 2;
|
||||||
public const int NOTIFY_KEYBOARD = 3;
|
public const int NotifyKeyboard = 3;
|
||||||
public const int CLEAR_CLIPBOARD = 4;
|
public const int ClearClipboard = 4;
|
||||||
|
|
||||||
|
|
||||||
public CopyToClipboardService (IntPtr javaReference, JniHandleOwnership transfer)
|
public CopyToClipboardService (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
@ -51,8 +55,8 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyToClipboardBroadcastReceiver mCopyToClipBroadcastReceiver;
|
CopyToClipboardBroadcastReceiver _copyToClipBroadcastReceiver;
|
||||||
NotificationDeletedBroadcastReceiver mNotificationDeletedBroadcastReceiver;
|
NotificationDeletedBroadcastReceiver _notificationDeletedBroadcastReceiver;
|
||||||
|
|
||||||
|
|
||||||
public CopyToClipboardService()
|
public CopyToClipboardService()
|
||||||
@ -60,11 +64,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public override void OnCreate()
|
|
||||||
{
|
|
||||||
base.OnCreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IBinder OnBind(Intent intent)
|
public override IBinder OnBind(Intent intent)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -74,17 +74,17 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
Android.Util.Log.Debug("DEBUG","Received intent to provide access to entry");
|
Android.Util.Log.Debug("DEBUG","Received intent to provide access to entry");
|
||||||
|
|
||||||
String uuidBytes = intent.GetStringExtra(EntryActivity.KEY_ENTRY);
|
String uuidBytes = intent.GetStringExtra(EntryActivity.KeyEntry);
|
||||||
bool closeAfterCreate = intent.GetBooleanExtra(EntryActivity.KEY_CLOSE_AFTER_CREATE, false);
|
bool closeAfterCreate = intent.GetBooleanExtra(EntryActivity.KeyCloseAfterCreate, false);
|
||||||
|
|
||||||
PwUuid entryId = PwUuid.Zero;
|
PwUuid entryId = PwUuid.Zero;
|
||||||
if (uuidBytes != null)
|
if (uuidBytes != null)
|
||||||
entryId = new KeePassLib.PwUuid(MemUtil.HexStringToByteArray(uuidBytes));
|
entryId = new PwUuid(MemUtil.HexStringToByteArray(uuidBytes));
|
||||||
|
|
||||||
PwEntry entry;
|
PwEntry entry;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
entry = App.getDB().entries[entryId];
|
entry = App.Kp2a.GetDb().Entries[entryId];
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch(Exception)
|
||||||
{
|
{
|
||||||
@ -93,29 +93,29 @@ namespace keepass2android
|
|||||||
return StartCommandResult.NotSticky;
|
return StartCommandResult.NotSticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayAccessNotifications(entry, closeAfterCreate);
|
DisplayAccessNotifications(entry, closeAfterCreate);
|
||||||
|
|
||||||
|
|
||||||
return StartCommandResult.RedeliverIntent;
|
return StartCommandResult.RedeliverIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationManager mNM;
|
private NotificationManager _notificationManager;
|
||||||
private int mNumElementsToWaitFor = 0;
|
private int _numElementsToWaitFor;
|
||||||
|
|
||||||
public override void OnDestroy()
|
public override void OnDestroy()
|
||||||
{
|
{
|
||||||
// These members might never get initialized if the app timed out
|
// These members might never get initialized if the app timed out
|
||||||
if (mCopyToClipBroadcastReceiver != null)
|
if (_copyToClipBroadcastReceiver != null)
|
||||||
{
|
{
|
||||||
UnregisterReceiver(mCopyToClipBroadcastReceiver);
|
UnregisterReceiver(_copyToClipBroadcastReceiver);
|
||||||
}
|
}
|
||||||
if (mNotificationDeletedBroadcastReceiver != null)
|
if (_notificationDeletedBroadcastReceiver != null)
|
||||||
{
|
{
|
||||||
UnregisterReceiver(mNotificationDeletedBroadcastReceiver);
|
UnregisterReceiver(_notificationDeletedBroadcastReceiver);
|
||||||
}
|
}
|
||||||
if ( mNM != null ) {
|
if ( _notificationManager != null ) {
|
||||||
mNM.CancelAll();
|
_notificationManager.CancelAll();
|
||||||
mNumElementsToWaitFor= 0;
|
_numElementsToWaitFor= 0;
|
||||||
clearKeyboard();
|
clearKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +124,13 @@ namespace keepass2android
|
|||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
static string ACTION_NOTIFICATION_CANCELLED = "notification_cancelled";
|
private const string ActionNotificationCancelled = "notification_cancelled";
|
||||||
|
|
||||||
//creates a delete intent (started when notification is cancelled by user or something else)
|
//creates a delete intent (started when notification is cancelled by user or something else)
|
||||||
//requires different request codes for every item (otherwise the intents are identical)
|
//requires different request codes for every item (otherwise the intents are identical)
|
||||||
PendingIntent createDeleteIntent(int requestCode)
|
PendingIntent CreateDeleteIntent(int requestCode)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(ACTION_NOTIFICATION_CANCELLED);
|
Intent intent = new Intent(ActionNotificationCancelled);
|
||||||
Bundle extra = new Bundle();
|
Bundle extra = new Bundle();
|
||||||
extra.PutInt("requestCode", requestCode);
|
extra.PutInt("requestCode", requestCode);
|
||||||
intent.PutExtras(extra);
|
intent.PutExtras(extra);
|
||||||
@ -138,39 +138,39 @@ namespace keepass2android
|
|||||||
return PendingIntent.GetBroadcast(this, requestCode, intent, PendingIntentFlags.CancelCurrent);
|
return PendingIntent.GetBroadcast(this, requestCode, intent, PendingIntentFlags.CancelCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayAccessNotifications(PwEntry entry, bool closeAfterCreate)
|
public void DisplayAccessNotifications(PwEntry entry, bool closeAfterCreate)
|
||||||
{
|
{
|
||||||
// Notification Manager
|
// Notification Manager
|
||||||
mNM = (NotificationManager)GetSystemService(NotificationService);
|
_notificationManager = (NotificationManager)GetSystemService(NotificationService);
|
||||||
|
|
||||||
mNM.CancelAll();
|
_notificationManager.CancelAll();
|
||||||
mNumElementsToWaitFor = 0;
|
_numElementsToWaitFor = 0;
|
||||||
clearKeyboard();
|
clearKeyboard();
|
||||||
|
|
||||||
String entryName = entry.Strings.ReadSafe(PwDefs.TitleField);
|
String entryName = entry.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
|
|
||||||
ISharedPreferences prefs = Android.Preferences.PreferenceManager.GetDefaultSharedPreferences(this);
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
if (prefs.GetBoolean(GetString(Resource.String.CopyToClipboardNotification_key), Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)))
|
if (prefs.GetBoolean(GetString(Resource.String.CopyToClipboardNotification_key), Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (GetStringAndReplacePlaceholders(entry, PwDefs.PasswordField).Length > 0)
|
if (GetStringAndReplacePlaceholders(entry, PwDefs.PasswordField).Length > 0)
|
||||||
{
|
{
|
||||||
// only show notification if password is available
|
// only show notification if password is available
|
||||||
Notification password = GetNotification(Intents.COPY_PASSWORD, Resource.String.copy_password, Resource.Drawable.notify, entryName);
|
Notification password = GetNotification(Intents.CopyPassword, Resource.String.copy_password, Resource.Drawable.notify, entryName);
|
||||||
|
|
||||||
password.DeleteIntent = createDeleteIntent(NOTIFY_PASSWORD);
|
password.DeleteIntent = CreateDeleteIntent(NotifyPassword);
|
||||||
mNM.Notify(NOTIFY_PASSWORD, password);
|
_notificationManager.Notify(NotifyPassword, password);
|
||||||
mNumElementsToWaitFor++;
|
_numElementsToWaitFor++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetStringAndReplacePlaceholders(entry, PwDefs.UserNameField).Length > 0)
|
if (GetStringAndReplacePlaceholders(entry, PwDefs.UserNameField).Length > 0)
|
||||||
{
|
{
|
||||||
// only show notification if username is available
|
// only show notification if username is available
|
||||||
Notification username = GetNotification(Intents.COPY_USERNAME, Resource.String.copy_username, Resource.Drawable.notify, entryName);
|
Notification username = GetNotification(Intents.CopyUsername, Resource.String.copy_username, Resource.Drawable.notify, entryName);
|
||||||
username.DeleteIntent = createDeleteIntent(NOTIFY_USERNAME);
|
username.DeleteIntent = CreateDeleteIntent(NotifyUsername);
|
||||||
mNumElementsToWaitFor++;
|
_numElementsToWaitFor++;
|
||||||
mNM.Notify(NOTIFY_USERNAME, username);
|
_notificationManager.Notify(NotifyUsername, username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,17 +178,17 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
|
|
||||||
//keyboard
|
//keyboard
|
||||||
if (makeAccessibleForKeyboard(entry))
|
if (MakeAccessibleForKeyboard(entry))
|
||||||
{
|
{
|
||||||
// only show notification if username is available
|
// only show notification if username is available
|
||||||
Notification keyboard = GetNotification(Intents.CHECK_KEYBOARD, Resource.String.available_through_keyboard, Resource.Drawable.notify_keyboard, entryName);
|
Notification keyboard = GetNotification(Intents.CheckKeyboard, Resource.String.available_through_keyboard, Resource.Drawable.notify_keyboard, entryName);
|
||||||
keyboard.DeleteIntent = createDeleteIntent(NOTIFY_KEYBOARD);
|
keyboard.DeleteIntent = CreateDeleteIntent(NotifyKeyboard);
|
||||||
mNumElementsToWaitFor++;
|
_numElementsToWaitFor++;
|
||||||
mNM.Notify(NOTIFY_KEYBOARD, keyboard);
|
_notificationManager.Notify(NotifyKeyboard, keyboard);
|
||||||
|
|
||||||
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
//if the app is about to be closed again (e.g. after searching for a URL and returning to the browser:
|
||||||
// automatically bring up the Keyboard selection dialog
|
// automatically bring up the Keyboard selection dialog
|
||||||
if ((closeAfterCreate) && (prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)) == true))
|
if ((closeAfterCreate) && prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||||
{
|
{
|
||||||
ActivateKp2aKeyboard(this);
|
ActivateKp2aKeyboard(this);
|
||||||
}
|
}
|
||||||
@ -196,28 +196,28 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNumElementsToWaitFor == 0)
|
if (_numElementsToWaitFor == 0)
|
||||||
{
|
{
|
||||||
StopSelf();
|
StopSelf();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCopyToClipBroadcastReceiver = new CopyToClipboardBroadcastReceiver(entry, this);
|
_copyToClipBroadcastReceiver = new CopyToClipboardBroadcastReceiver(entry, this);
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.AddAction(Intents.COPY_USERNAME);
|
filter.AddAction(Intents.CopyUsername);
|
||||||
filter.AddAction(Intents.COPY_PASSWORD);
|
filter.AddAction(Intents.CopyPassword);
|
||||||
filter.AddAction(Intents.CHECK_KEYBOARD);
|
filter.AddAction(Intents.CheckKeyboard);
|
||||||
RegisterReceiver(mCopyToClipBroadcastReceiver, filter);
|
RegisterReceiver(_copyToClipBroadcastReceiver, filter);
|
||||||
|
|
||||||
//register receiver to get notified when notifications are discarded in which case we can shutdown the service
|
//register receiver to get notified when notifications are discarded in which case we can shutdown the service
|
||||||
mNotificationDeletedBroadcastReceiver = new NotificationDeletedBroadcastReceiver(this);
|
_notificationDeletedBroadcastReceiver = new NotificationDeletedBroadcastReceiver(this);
|
||||||
IntentFilter deletefilter = new IntentFilter();
|
IntentFilter deletefilter = new IntentFilter();
|
||||||
deletefilter.AddAction(ACTION_NOTIFICATION_CANCELLED);
|
deletefilter.AddAction(ActionNotificationCancelled);
|
||||||
RegisterReceiver(mNotificationDeletedBroadcastReceiver, deletefilter);
|
RegisterReceiver(_notificationDeletedBroadcastReceiver, deletefilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool makeAccessibleForKeyboard(PwEntry entry)
|
bool MakeAccessibleForKeyboard(PwEntry entry)
|
||||||
{
|
{
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder();
|
Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder();
|
||||||
@ -271,18 +271,18 @@ namespace keepass2android
|
|||||||
static string GetStringAndReplacePlaceholders(PwEntry entry, string key)
|
static string GetStringAndReplacePlaceholders(PwEntry entry, string key)
|
||||||
{
|
{
|
||||||
String value = entry.Strings.ReadSafe(key);
|
String value = entry.Strings.ReadSafe(key);
|
||||||
value = SprEngine.Compile(value, new SprContext(entry, App.getDB().pm, SprCompileFlags.All));
|
value = SprEngine.Compile(value, new SprContext(entry, App.Kp2a.GetDb().KpDatabase, SprCompileFlags.All));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnWaitElementDeleted(int itemId)
|
public void OnWaitElementDeleted(int itemId)
|
||||||
{
|
{
|
||||||
mNumElementsToWaitFor--;
|
_numElementsToWaitFor--;
|
||||||
if (mNumElementsToWaitFor <= 0)
|
if (_numElementsToWaitFor <= 0)
|
||||||
{
|
{
|
||||||
StopSelf();
|
StopSelf();
|
||||||
}
|
}
|
||||||
if (itemId == NOTIFY_KEYBOARD)
|
if (itemId == NotifyKeyboard)
|
||||||
{
|
{
|
||||||
//keyboard notification was deleted -> clear entries in keyboard
|
//keyboard notification was deleted -> clear entries in keyboard
|
||||||
clearKeyboard();
|
clearKeyboard();
|
||||||
@ -295,9 +295,9 @@ namespace keepass2android
|
|||||||
Keepass2android.Kbbridge.KeyboardData.EntryName = null;
|
Keepass2android.Kbbridge.KeyboardData.EntryName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Timer mTimer = new Timer();
|
private readonly Timer _timer = new Timer();
|
||||||
|
|
||||||
internal void timeoutCopyToClipboard(String text) {
|
internal void TimeoutCopyToClipboard(String text) {
|
||||||
Util.copyToClipboard(this, text);
|
Util.copyToClipboard(this, text);
|
||||||
|
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
@ -306,31 +306,31 @@ namespace keepass2android
|
|||||||
long clipClearTime = long.Parse(sClipClear);
|
long clipClearTime = long.Parse(sClipClear);
|
||||||
|
|
||||||
if ( clipClearTime > 0 ) {
|
if ( clipClearTime > 0 ) {
|
||||||
mNumElementsToWaitFor++;
|
_numElementsToWaitFor++;
|
||||||
mTimer.Schedule(new ClearClipboardTask(this, text, uiThreadCallback), clipClearTime);
|
_timer.Schedule(new ClearClipboardTask(this, text, _uiThreadCallback), clipClearTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task which clears the clipboard, and sends a toast to the foreground.
|
// Task which clears the clipboard, and sends a toast to the foreground.
|
||||||
private class ClearClipboardTask : Java.Util.TimerTask {
|
private class ClearClipboardTask : TimerTask {
|
||||||
|
|
||||||
private String mClearText;
|
private readonly String _clearText;
|
||||||
private CopyToClipboardService mService;
|
private readonly CopyToClipboardService _service;
|
||||||
private Handler handler;
|
private readonly Handler _handler;
|
||||||
|
|
||||||
public ClearClipboardTask(CopyToClipboardService service, String clearText, Handler handler) {
|
public ClearClipboardTask(CopyToClipboardService service, String clearText, Handler handler) {
|
||||||
mClearText = clearText;
|
_clearText = clearText;
|
||||||
mService = service;
|
_service = service;
|
||||||
this.handler = handler;
|
_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Run() {
|
public override void Run() {
|
||||||
String currentClip = Util.getClipboard(mService);
|
String currentClip = Util.getClipboard(_service);
|
||||||
handler.Post( () => { mService.OnWaitElementDeleted(CLEAR_CLIPBOARD); });
|
_handler.Post( () => _service.OnWaitElementDeleted(ClearClipboard));
|
||||||
if ( currentClip.Equals(mClearText) ) {
|
if ( currentClip.Equals(_clearText) ) {
|
||||||
Util.copyToClipboard(mService, "");
|
Util.copyToClipboard(_service, "");
|
||||||
handler.Post( () => {
|
_handler.Post( () => {
|
||||||
Toast.MakeText(mService, Resource.String.ClearClipboard, ToastLength.Long).Show();
|
Toast.MakeText(_service, Resource.String.ClearClipboard, ToastLength.Long).Show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
// Setup to allow the toast to happen in the foreground
|
// Setup to allow the toast to happen in the foreground
|
||||||
Handler uiThreadCallback = new Handler();
|
readonly Handler _uiThreadCallback = new Handler();
|
||||||
|
|
||||||
private Notification GetNotification(String intentText, int descResId, int drawableResId, String entryName) {
|
private Notification GetNotification(String intentText, int descResId, int drawableResId, String entryName) {
|
||||||
String desc = GetString(descResId);
|
String desc = GetString(descResId);
|
||||||
@ -362,36 +362,37 @@ namespace keepass2android
|
|||||||
|
|
||||||
class CopyToClipboardBroadcastReceiver: BroadcastReceiver
|
class CopyToClipboardBroadcastReceiver: BroadcastReceiver
|
||||||
{
|
{
|
||||||
CopyToClipboardService mService;
|
readonly CopyToClipboardService _service;
|
||||||
|
readonly PwEntry _entry;
|
||||||
|
|
||||||
public CopyToClipboardBroadcastReceiver(PwEntry entry, CopyToClipboardService service)
|
public CopyToClipboardBroadcastReceiver(PwEntry entry, CopyToClipboardService service)
|
||||||
{
|
{
|
||||||
mEntry = entry;
|
_entry = entry;
|
||||||
this.mService = service;
|
_service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
PwEntry mEntry;
|
|
||||||
|
|
||||||
public override void OnReceive(Context context, Intent intent)
|
public override void OnReceive(Context context, Intent intent)
|
||||||
{
|
{
|
||||||
String action = intent.Action;
|
String action = intent.Action;
|
||||||
|
|
||||||
if (action.Equals(Intents.COPY_USERNAME))
|
if (action.Equals(Intents.CopyUsername))
|
||||||
{
|
{
|
||||||
String username = GetStringAndReplacePlaceholders(mEntry, PwDefs.UserNameField);
|
String username = GetStringAndReplacePlaceholders(_entry, PwDefs.UserNameField);
|
||||||
if (username.Length > 0)
|
if (username.Length > 0)
|
||||||
{
|
{
|
||||||
mService.timeoutCopyToClipboard(username);
|
_service.TimeoutCopyToClipboard(username);
|
||||||
}
|
}
|
||||||
} else if (action.Equals(Intents.COPY_PASSWORD))
|
} else if (action.Equals(Intents.CopyPassword))
|
||||||
{
|
{
|
||||||
String password = GetStringAndReplacePlaceholders(mEntry, PwDefs.PasswordField);
|
String password = GetStringAndReplacePlaceholders(_entry, PwDefs.PasswordField);
|
||||||
if (password.Length > 0)
|
if (password.Length > 0)
|
||||||
{
|
{
|
||||||
mService.timeoutCopyToClipboard(password);
|
_service.TimeoutCopyToClipboard(password);
|
||||||
}
|
}
|
||||||
} else if (action.Equals(Intents.CHECK_KEYBOARD))
|
} else if (action.Equals(Intents.CheckKeyboard))
|
||||||
{
|
{
|
||||||
CopyToClipboardService.ActivateKp2aKeyboard(mService);
|
ActivateKp2aKeyboard(_service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,18 +400,18 @@ namespace keepass2android
|
|||||||
|
|
||||||
class NotificationDeletedBroadcastReceiver: BroadcastReceiver
|
class NotificationDeletedBroadcastReceiver: BroadcastReceiver
|
||||||
{
|
{
|
||||||
CopyToClipboardService mService;
|
readonly CopyToClipboardService _service;
|
||||||
public NotificationDeletedBroadcastReceiver(CopyToClipboardService service)
|
public NotificationDeletedBroadcastReceiver(CopyToClipboardService service)
|
||||||
{
|
{
|
||||||
this.mService = service;
|
_service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region implemented abstract members of BroadcastReceiver
|
#region implemented abstract members of BroadcastReceiver
|
||||||
public override void OnReceive(Context context, Intent intent)
|
public override void OnReceive(Context context, Intent intent)
|
||||||
{
|
{
|
||||||
if (intent.Action == CopyToClipboardService.ACTION_NOTIFICATION_CANCELLED)
|
if (intent.Action == ActionNotificationCancelled)
|
||||||
{
|
{
|
||||||
mService.OnWaitElementDeleted(intent.Extras.GetInt("requestCode"));
|
_service.OnWaitElementDeleted(intent.Extras.GetInt("requestCode"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -424,7 +425,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
string kp2aIme = service.PackageName + "/keepass2android.softkeyboard.KP2AKeyboard";
|
string kp2aIme = service.PackageName + "/keepass2android.softkeyboard.KP2AKeyboard";
|
||||||
|
|
||||||
InputMethodManager imeManager = (InputMethodManager)service.ApplicationContext.GetSystemService(Context.InputMethodService);
|
InputMethodManager imeManager = (InputMethodManager)service.ApplicationContext.GetSystemService(InputMethodService);
|
||||||
|
|
||||||
if (currentIme == kp2aIme)
|
if (currentIme == kp2aIme)
|
||||||
{
|
{
|
||||||
|
@ -15,25 +15,19 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Support.V4.App;
|
using Android.Support.V4.App;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
//This service is started as soon as a Database with QuickUnlock enabled is opened.
|
/// <summary>
|
||||||
//Its only purpose is to be a foreground service which prevents the App from being killed (in most situations)
|
/// This service is started as soon as a Database with QuickUnlock enabled is opened.
|
||||||
[Service]
|
/// Its only purpose is to be a foreground service which prevents the App from being killed (in most situations)
|
||||||
|
/// </summary>
|
||||||
|
[Service]
|
||||||
public class QuickUnlockForegroundService : Service
|
public class QuickUnlockForegroundService : Service
|
||||||
{
|
{
|
||||||
public override IBinder OnBind(Intent intent)
|
public override IBinder OnBind(Intent intent)
|
||||||
|
@ -16,44 +16,41 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Util;
|
using Android.Util;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages timeout to lock the database after some idle time
|
||||||
|
/// </summary>
|
||||||
[Service]
|
[Service]
|
||||||
public class TimeoutService : Service {
|
public class TimeoutService : Service {
|
||||||
private const String TAG = "KeePass2Android Timer";
|
private const String Tag = "KeePass2Android Timer";
|
||||||
private BroadcastReceiver mIntentReceiver;
|
private BroadcastReceiver _intentReceiver;
|
||||||
|
|
||||||
|
|
||||||
public TimeoutService (IntPtr javaReference, JniHandleOwnership transfer)
|
public TimeoutService (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
{
|
{
|
||||||
mBinder = new TimeoutBinder(this);
|
_binder = new TimeoutBinder(this);
|
||||||
}
|
}
|
||||||
public TimeoutService()
|
public TimeoutService()
|
||||||
{
|
{
|
||||||
mBinder = new TimeoutBinder(this);
|
_binder = new TimeoutBinder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCreate() {
|
public override void OnCreate() {
|
||||||
base.OnCreate();
|
base.OnCreate();
|
||||||
|
|
||||||
mIntentReceiver = new MyBroadcastReceiver(this);
|
_intentReceiver = new MyBroadcastReceiver(this);
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.AddAction(Intents.TIMEOUT);
|
filter.AddAction(Intents.Timeout);
|
||||||
RegisterReceiver(mIntentReceiver, filter);
|
RegisterReceiver(_intentReceiver, filter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +58,12 @@ namespace keepass2android
|
|||||||
public override void OnStart(Intent intent, int startId) {
|
public override void OnStart(Intent intent, int startId) {
|
||||||
base.OnStart(intent, startId);
|
base.OnStart(intent, startId);
|
||||||
|
|
||||||
Log.Debug(TAG, "Timeout service started");
|
Log.Debug(Tag, "Timeout service started");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void timeout(Context context) {
|
private void Timeout() {
|
||||||
Log.Debug(TAG, "Timeout");
|
Log.Debug(Tag, "Timeout");
|
||||||
App.setShutdown();
|
App.Kp2a.SetShutdown();
|
||||||
|
|
||||||
NotificationManager nm = (NotificationManager) GetSystemService(NotificationService);
|
NotificationManager nm = (NotificationManager) GetSystemService(NotificationService);
|
||||||
nm.CancelAll();
|
nm.CancelAll();
|
||||||
@ -77,30 +74,30 @@ namespace keepass2android
|
|||||||
public override void OnDestroy() {
|
public override void OnDestroy() {
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
|
|
||||||
Log.Debug(TAG, "Timeout service stopped");
|
Log.Debug(Tag, "Timeout service stopped");
|
||||||
|
|
||||||
UnregisterReceiver(mIntentReceiver);
|
UnregisterReceiver(_intentReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TimeoutBinder : Binder
|
public class TimeoutBinder : Binder
|
||||||
{
|
{
|
||||||
TimeoutService service;
|
readonly TimeoutService _service;
|
||||||
|
|
||||||
public TimeoutBinder(TimeoutService service)
|
public TimeoutBinder(TimeoutService service)
|
||||||
{
|
{
|
||||||
this.service = service;
|
_service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeoutService getService() {
|
public TimeoutService GetService() {
|
||||||
return service;
|
return _service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBinder mBinder;
|
private readonly IBinder _binder;
|
||||||
|
|
||||||
|
|
||||||
public override IBinder OnBind(Intent intent) {
|
public override IBinder OnBind(Intent intent) {
|
||||||
return mBinder;
|
return _binder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BroadcastReceiver]
|
[BroadcastReceiver]
|
||||||
@ -112,17 +109,17 @@ namespace keepass2android
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeoutService timeoutService;
|
readonly TimeoutService _timeoutService;
|
||||||
public MyBroadcastReceiver (TimeoutService timeoutService)
|
public MyBroadcastReceiver (TimeoutService timeoutService)
|
||||||
{
|
{
|
||||||
this.timeoutService = timeoutService;
|
_timeoutService = timeoutService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReceive(Context context, Intent intent) {
|
public override void OnReceive(Context context, Intent intent) {
|
||||||
String action = intent.Action;
|
String action = intent.Action;
|
||||||
|
|
||||||
if ( action.Equals(Intents.TIMEOUT) ) {
|
if ( action.Equals(Intents.Timeout) ) {
|
||||||
timeoutService.timeout(context);
|
_timeoutService.Timeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,24 +16,22 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using KeePassLib.Cryptography.Cipher;
|
using KeePassLib.Cryptography.Cipher;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Activity to configure the app
|
||||||
|
/// </summary>
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
||||||
public class AppSettingsActivity : LockingClosePreferenceActivity {
|
public class AppSettingsActivity : LockingClosePreferenceActivity {
|
||||||
public static bool KEYFILE_DEFAULT = false;
|
public static bool KeyfileDefault = false;
|
||||||
|
|
||||||
public static void Launch(Context ctx) {
|
public static void Launch(Context ctx) {
|
||||||
Intent i = new Intent(ctx, typeof(AppSettingsActivity));
|
Intent i = new Intent(ctx, typeof(AppSettingsActivity));
|
||||||
@ -47,74 +45,67 @@ namespace keepass2android
|
|||||||
AddPreferencesFromResource(Resource.Xml.preferences);
|
AddPreferencesFromResource(Resource.Xml.preferences);
|
||||||
|
|
||||||
Preference keyFile = FindPreference(GetString(Resource.String.keyfile_key));
|
Preference keyFile = FindPreference(GetString(Resource.String.keyfile_key));
|
||||||
keyFile.PreferenceChange += (object sender, Preference.PreferenceChangeEventArgs e) =>
|
keyFile.PreferenceChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
bool value = (bool) e.NewValue;
|
bool value = (bool) e.NewValue;
|
||||||
|
|
||||||
if ( ! value ) {
|
if ( ! value ) {
|
||||||
FileDbHelper helper = App.fileDbHelper;
|
FileDbHelper helper = App.Kp2a.FileDbHelper;
|
||||||
|
|
||||||
helper.deleteAllKeys();
|
helper.DeleteAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
if ( db.Open ) {
|
if ( db.Open ) {
|
||||||
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
|
Preference rounds = FindPreference(GetString(Resource.String.rounds_key));
|
||||||
rounds.PreferenceChange += (object sender, Preference.PreferenceChangeEventArgs e) =>
|
rounds.PreferenceChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
setRounds(App.getDB(), e.Preference);
|
setRounds(App.Kp2a.GetDb(), e.Preference);
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
|
Preference defaultUser = FindPreference(GetString(Resource.String.default_username_key));
|
||||||
((EditTextPreference)defaultUser).EditText.Text = db.pm.DefaultUserName;
|
((EditTextPreference)defaultUser).EditText.Text = db.KpDatabase.DefaultUserName;
|
||||||
((EditTextPreference)defaultUser).Text = db.pm.DefaultUserName;
|
((EditTextPreference)defaultUser).Text = db.KpDatabase.DefaultUserName;
|
||||||
defaultUser.PreferenceChange += (object sender, Preference.PreferenceChangeEventArgs e) =>
|
defaultUser.PreferenceChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
DateTime previousUsernameChanged = db.pm.DefaultUserNameChanged;
|
DateTime previousUsernameChanged = db.KpDatabase.DefaultUserNameChanged;
|
||||||
String previousUsername = db.pm.DefaultUserName;
|
String previousUsername = db.KpDatabase.DefaultUserName;
|
||||||
db.pm.DefaultUserName = e.NewValue.ToString();
|
db.KpDatabase.DefaultUserName = e.NewValue.ToString();
|
||||||
|
|
||||||
Handler handler = new Handler();
|
SaveDb save = new SaveDb(this, App.Kp2a.GetDb(), new ActionOnFinish( (success, message) =>
|
||||||
|
|
||||||
SaveDB save = new SaveDB(this, App.getDB(), new ActionOnFinish( (success, message) =>
|
|
||||||
{
|
{
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
db.pm.DefaultUserName = previousUsername;
|
db.KpDatabase.DefaultUserName = previousUsername;
|
||||||
db.pm.DefaultUserNameChanged = previousUsernameChanged;
|
db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
|
||||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
Toast.MakeText(this, message, ToastLength.Long).Show();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
ProgressTask pt = new ProgressTask(this, save, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, this, save, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
};
|
};
|
||||||
|
|
||||||
Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
|
Preference databaseName = FindPreference(GetString(Resource.String.database_name_key));
|
||||||
((EditTextPreference)databaseName).EditText.Text = db.pm.Name;
|
((EditTextPreference)databaseName).EditText.Text = db.KpDatabase.Name;
|
||||||
((EditTextPreference)databaseName).Text = db.pm.Name;
|
((EditTextPreference)databaseName).Text = db.KpDatabase.Name;
|
||||||
databaseName.PreferenceChange += (object sender, Preference.PreferenceChangeEventArgs e) =>
|
databaseName.PreferenceChange += (sender, e) =>
|
||||||
{
|
{
|
||||||
DateTime previousNameChanged = db.pm.NameChanged;
|
DateTime previousNameChanged = db.KpDatabase.NameChanged;
|
||||||
String previousName = db.pm.Name;
|
String previousName = db.KpDatabase.Name;
|
||||||
db.pm.Name = e.NewValue.ToString();
|
db.KpDatabase.Name = e.NewValue.ToString();
|
||||||
|
|
||||||
Handler handler = new Handler();
|
SaveDb save = new SaveDb(this, App.Kp2a.GetDb(), new ActionOnFinish( (success, message) =>
|
||||||
|
|
||||||
SaveDB save = new SaveDB(this, App.getDB(), new ActionOnFinish( (success, message) =>
|
|
||||||
{
|
{
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
db.pm.Name = previousName;
|
db.KpDatabase.Name = previousName;
|
||||||
db.pm.NameChanged = previousNameChanged;
|
db.KpDatabase.NameChanged = previousNameChanged;
|
||||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
Toast.MakeText(this, message, ToastLength.Long).Show();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
ProgressTask pt = new ProgressTask(this, save, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, this, save, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -130,19 +121,14 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStop() {
|
|
||||||
|
|
||||||
base.OnStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setRounds(Database db, Preference rounds) {
|
private void setRounds(Database db, Preference rounds) {
|
||||||
rounds.Summary = db.pm.KeyEncryptionRounds.ToString();
|
rounds.Summary = db.KpDatabase.KeyEncryptionRounds.ToString(CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAlgorithm(Database db, Preference algorithm) {
|
private void setAlgorithm(Database db, Preference algorithm) {
|
||||||
|
|
||||||
algorithm.Summary = CipherPool.GlobalPool.GetCipher(db.pm.DataCipherUuid).DisplayName;
|
algorithm.Summary = CipherPool.GlobalPool.GetCipher(db.KpDatabase.DataCipherUuid).DisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,30 +16,23 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utility class to simplify access to the app preferences
|
||||||
|
/// </summary>
|
||||||
public class PrefsUtil {
|
public class PrefsUtil {
|
||||||
public static float getListTextSize(Context ctx) {
|
public static float GetListTextSize(Context ctx) {
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
||||||
|
|
||||||
return float.Parse(prefs.GetString(ctx.GetString(Resource.String.list_size_key), ctx.GetString(Resource.String.list_size_default)));
|
return float.Parse(prefs.GetString(ctx.GetString(Resource.String.list_size_key), ctx.GetString(Resource.String.list_size_default)));
|
||||||
|
|
||||||
}
|
}
|
||||||
public static float getListDetailTextSize(Context ctx) {
|
public static float GetListDetailTextSize(Context ctx) {
|
||||||
return (float)Math.Round(getListTextSize(ctx)*3.0f/4.0f);
|
return (float)Math.Round(GetListTextSize(ctx)*3.0f/4.0f);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,38 +15,34 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Globalization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using Android.Util;
|
using Android.Util;
|
||||||
using keepass2android;
|
|
||||||
|
|
||||||
namespace keepass2android.settings
|
namespace keepass2android.settings
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the setting for the number of key transformation rounds. Changing this requires to save the database.
|
||||||
|
/// </summary>
|
||||||
public class RoundsPreference : DialogPreference {
|
public class RoundsPreference : DialogPreference {
|
||||||
|
|
||||||
internal PwDatabase mPM;
|
internal PwDatabase PwDatabase;
|
||||||
internal TextView mRoundsView;
|
internal TextView RoundsView;
|
||||||
|
|
||||||
protected override View OnCreateDialogView() {
|
protected override View OnCreateDialogView() {
|
||||||
View view = base.OnCreateDialogView();
|
View view = base.OnCreateDialogView();
|
||||||
|
|
||||||
mRoundsView = (TextView) view.FindViewById(Resource.Id.rounds);
|
RoundsView = (TextView) view.FindViewById(Resource.Id.rounds);
|
||||||
|
|
||||||
Database db = App.getDB();
|
Database db = App.Kp2a.GetDb();
|
||||||
mPM = db.pm;
|
PwDatabase = db.KpDatabase;
|
||||||
ulong numRounds = mPM.KeyEncryptionRounds;
|
ulong numRounds = PwDatabase.KeyEncryptionRounds;
|
||||||
mRoundsView.Text = numRounds.ToString();
|
RoundsView.Text = numRounds.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -63,7 +59,7 @@ namespace keepass2android.settings
|
|||||||
if ( positiveResult ) {
|
if ( positiveResult ) {
|
||||||
ulong rounds;
|
ulong rounds;
|
||||||
|
|
||||||
String strRounds = mRoundsView.Text;
|
String strRounds = RoundsView.Text;
|
||||||
if (!(ulong.TryParse(strRounds,out rounds)))
|
if (!(ulong.TryParse(strRounds,out rounds)))
|
||||||
{
|
{
|
||||||
Toast.MakeText(Context, Resource.String.error_rounds_not_number, ToastLength.Long).Show();
|
Toast.MakeText(Context, Resource.String.error_rounds_not_number, ToastLength.Long).Show();
|
||||||
@ -74,48 +70,48 @@ namespace keepass2android.settings
|
|||||||
rounds = 1;
|
rounds = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong oldRounds = mPM.KeyEncryptionRounds;
|
ulong oldRounds = PwDatabase.KeyEncryptionRounds;
|
||||||
|
|
||||||
if (oldRounds == rounds)
|
if (oldRounds == rounds)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPM.KeyEncryptionRounds = rounds;
|
PwDatabase.KeyEncryptionRounds = rounds;
|
||||||
|
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
SaveDB save = new SaveDB(Context, App.getDB(), new AfterSave(Context, handler, oldRounds, this));
|
SaveDb save = new SaveDb(Context, App.Kp2a.GetDb(), new AfterSave(Context, handler, oldRounds, this));
|
||||||
ProgressTask pt = new ProgressTask(Context, save, Resource.String.saving_database);
|
ProgressTask pt = new ProgressTask(App.Kp2a, Context, save, UiStringKey.saving_database);
|
||||||
pt.run();
|
pt.Run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AfterSave : OnFinish {
|
private class AfterSave : OnFinish {
|
||||||
private ulong mOldRounds;
|
private readonly ulong _oldRounds;
|
||||||
private Context mCtx;
|
private readonly Context _ctx;
|
||||||
private RoundsPreference pref;
|
private readonly RoundsPreference _pref;
|
||||||
|
|
||||||
public AfterSave(Context ctx, Handler handler, ulong oldRounds, RoundsPreference pref):base(handler) {
|
public AfterSave(Context ctx, Handler handler, ulong oldRounds, RoundsPreference pref):base(handler) {
|
||||||
|
|
||||||
this.pref = pref;
|
_pref = pref;
|
||||||
mCtx = ctx;
|
_ctx = ctx;
|
||||||
mOldRounds = oldRounds;
|
_oldRounds = oldRounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void run() {
|
public override void Run() {
|
||||||
if ( mSuccess ) {
|
if ( Success ) {
|
||||||
|
|
||||||
if ( pref.OnPreferenceChangeListener != null ) {
|
if ( _pref.OnPreferenceChangeListener != null ) {
|
||||||
pref.OnPreferenceChangeListener.OnPreferenceChange(pref, null);
|
_pref.OnPreferenceChangeListener.OnPreferenceChange(_pref, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayMessage(mCtx);
|
DisplayMessage(_ctx);
|
||||||
pref.mPM.KeyEncryptionRounds = mOldRounds;
|
_pref.PwDatabase.KeyEncryptionRounds = _oldRounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.run();
|
base.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,27 +16,75 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
|
||||||
using Android.Views;
|
|
||||||
using Android.Widget;
|
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
|
using Android.Util;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Helper class to simplify usage of timeout (lock after idle time) from the activities
|
||||||
|
/// </summary>
|
||||||
public class TimeoutHelper {
|
public class TimeoutHelper {
|
||||||
|
|
||||||
private const long DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
class Timeout
|
||||||
|
{
|
||||||
public static void pause(Activity act) {
|
private const int RequestId = 0;
|
||||||
|
private const long DefaultTimeout = 5 * 60 * 1000; // 5 minutes
|
||||||
|
private const String Tag = "Keepass2Android Timeout";
|
||||||
|
|
||||||
|
private static PendingIntent BuildIntent(Context ctx)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(Intents.Timeout);
|
||||||
|
PendingIntent sender = PendingIntent.GetBroadcast(ctx, RequestId, intent, PendingIntentFlags.CancelCurrent);
|
||||||
|
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Start(Context ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
||||||
|
String sTimeout = prefs.GetString(ctx.GetString(Resource.String.app_timeout_key), ctx.GetString(Resource.String.clipboard_timeout_default));
|
||||||
|
|
||||||
|
long timeout;
|
||||||
|
if (!long.TryParse(sTimeout, out timeout))
|
||||||
|
{
|
||||||
|
timeout = DefaultTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout == -1)
|
||||||
|
{
|
||||||
|
// No timeout don't start timeout service
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.StartService(new Intent(ctx, typeof(TimeoutService)));
|
||||||
|
|
||||||
|
long triggerTime = Java.Lang.JavaSystem.CurrentTimeMillis() + timeout;
|
||||||
|
AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService);
|
||||||
|
|
||||||
|
Log.Debug(Tag, "Timeout start");
|
||||||
|
am.Set(AlarmType.Rtc, triggerTime, BuildIntent(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Cancel(Context ctx)
|
||||||
|
{
|
||||||
|
AlarmManager am = (AlarmManager)ctx.GetSystemService(Context.AlarmService);
|
||||||
|
|
||||||
|
Log.Debug(Tag, "Timeout cancel");
|
||||||
|
am.Cancel(BuildIntent(ctx));
|
||||||
|
|
||||||
|
ctx.StopService(new Intent(ctx, typeof(TimeoutService)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Pause(Activity act) {
|
||||||
// Record timeout time in case timeout service is killed
|
// Record timeout time in case timeout service is killed
|
||||||
long time = Java.Lang.JavaSystem.CurrentTimeMillis();
|
long time = Java.Lang.JavaSystem.CurrentTimeMillis();
|
||||||
|
|
||||||
@ -44,58 +92,57 @@ namespace keepass2android
|
|||||||
ISharedPreferencesEditor edit = prefs.Edit();
|
ISharedPreferencesEditor edit = prefs.Edit();
|
||||||
edit.PutLong(act.GetString(Resource.String.timeout_key), time);
|
edit.PutLong(act.GetString(Resource.String.timeout_key), time);
|
||||||
|
|
||||||
EditorCompat.apply(edit);
|
EditorCompat.Apply(edit);
|
||||||
|
|
||||||
if ( App.getDB().Open ) {
|
if ( App.Kp2a.GetDb().Open ) {
|
||||||
Timeout.start(act);
|
Timeout.Start(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void resume(Activity act) {
|
public static void Resume(Activity act) {
|
||||||
if ( App.getDB().Loaded ) {
|
if ( App.Kp2a.GetDb().Loaded ) {
|
||||||
Timeout.cancel(act);
|
Timeout.Cancel(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check whether the timeout has expired
|
// Check whether the timeout has expired
|
||||||
long cur_time = Java.Lang.JavaSystem.CurrentTimeMillis();
|
long curTime = Java.Lang.JavaSystem.CurrentTimeMillis();
|
||||||
|
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
||||||
long timeout_start = prefs.GetLong(act.GetString(Resource.String.timeout_key), -1);
|
long timeoutStart = prefs.GetLong(act.GetString(Resource.String.timeout_key), -1);
|
||||||
// The timeout never started
|
// The timeout never started
|
||||||
if (timeout_start == -1) {
|
if (timeoutStart == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String sTimeout = prefs.GetString(act.GetString(Resource.String.app_timeout_key), act.GetString(Resource.String.clipboard_timeout_default));
|
String sTimeout = prefs.GetString(act.GetString(Resource.String.app_timeout_key), act.GetString(Resource.String.clipboard_timeout_default));
|
||||||
long timeout = DEFAULT_TIMEOUT;
|
long timeout;
|
||||||
long.TryParse(sTimeout,out timeout);
|
if (!long.TryParse(sTimeout, out timeout))
|
||||||
|
{
|
||||||
// We are set to never timeout
|
// We are set to never timeout
|
||||||
if (timeout == -1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long diff = cur_time - timeout_start;
|
long diff = curTime - timeoutStart;
|
||||||
if (diff >= timeout) {
|
if (diff >= timeout) {
|
||||||
// We have timed out
|
// We have timed out
|
||||||
App.setShutdown();
|
App.Kp2a.SetShutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool iocChanged(IOConnectionInfo ioc, IOConnectionInfo other)
|
static bool IocChanged(IOConnectionInfo ioc, IOConnectionInfo other)
|
||||||
{
|
{
|
||||||
if ((ioc == null) || (other == null)) return false;
|
if ((ioc == null) || (other == null)) return false;
|
||||||
return ioc.GetDisplayName() != other.GetDisplayName();
|
return ioc.GetDisplayName() != other.GetDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool checkShutdown(Activity act, IOConnectionInfo ioc) {
|
public static bool CheckShutdown(Activity act, IOConnectionInfo ioc) {
|
||||||
if (( App.getDB().Loaded && (App.isShutdown() || App.getDB().Locked) )
|
if (( App.Kp2a.GetDb().Loaded && (App.Kp2a.IsShutdown() || App.Kp2a.GetDb().Locked) )
|
||||||
|| (iocChanged(ioc, App.getDB().mIoc))) //file was changed from ActionSend-Intent
|
|| (IocChanged(ioc, App.Kp2a.GetDb().Ioc))) //file was changed from ActionSend-Intent
|
||||||
{
|
{
|
||||||
act.SetResult(KeePass.EXIT_LOCK);
|
act.SetResult(KeePass.ExitLock);
|
||||||
act.Finish();
|
act.Finish();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
||||||
|
|
||||||
Keepass2Android is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Keepass2Android is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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 Android.Preferences;
|
|
||||||
using Android.Util;
|
|
||||||
|
|
||||||
namespace keepass2android
|
|
||||||
{
|
|
||||||
|
|
||||||
public class Timeout {
|
|
||||||
private const int REQUEST_ID = 0;
|
|
||||||
private const long DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes
|
|
||||||
private static String TAG = "Keepass2Android Timeout";
|
|
||||||
|
|
||||||
private static PendingIntent buildIntent(Context ctx) {
|
|
||||||
Intent intent = new Intent(Intents.TIMEOUT);
|
|
||||||
PendingIntent sender = PendingIntent.GetBroadcast(ctx, REQUEST_ID, intent, PendingIntentFlags.CancelCurrent);
|
|
||||||
|
|
||||||
return sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void start(Context ctx) {
|
|
||||||
|
|
||||||
|
|
||||||
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(ctx);
|
|
||||||
String sTimeout = prefs.GetString(ctx.GetString(Resource.String.app_timeout_key), ctx.GetString(Resource.String.clipboard_timeout_default));
|
|
||||||
|
|
||||||
long timeout;
|
|
||||||
if (!long.TryParse(sTimeout, out timeout))
|
|
||||||
{
|
|
||||||
timeout = DEFAULT_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( timeout == -1 ) {
|
|
||||||
// No timeout don't start timeout service
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.StartService(new Intent(ctx, typeof(TimeoutService)));
|
|
||||||
|
|
||||||
long triggerTime = Java.Lang.JavaSystem.CurrentTimeMillis() + timeout;
|
|
||||||
AlarmManager am = (AlarmManager) ctx.GetSystemService(Context.AlarmService);
|
|
||||||
|
|
||||||
Log.Debug(TAG, "Timeout start");
|
|
||||||
am.Set(AlarmType.Rtc, triggerTime, buildIntent(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void cancel(Context ctx) {
|
|
||||||
AlarmManager am = (AlarmManager) ctx.GetSystemService(Context.AlarmService);
|
|
||||||
|
|
||||||
Log.Debug(TAG, "Timeout cancel");
|
|
||||||
am.Cancel(buildIntent(ctx));
|
|
||||||
|
|
||||||
ctx.StopService(new Intent(ctx, typeof(TimeoutService)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,29 +16,21 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Android.App;
|
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Util;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
|
|
||||||
namespace keepass2android.view
|
namespace keepass2android.view
|
||||||
{
|
{
|
||||||
public abstract class ClickView : LinearLayout {
|
public abstract class ClickView : LinearLayout {
|
||||||
|
protected ClickView (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
public ClickView (IntPtr javaReference, JniHandleOwnership transfer)
|
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClickView(Context context) :base(context)
|
protected ClickView(Context context) :base(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,15 +36,15 @@ namespace keepass2android.view
|
|||||||
}
|
}
|
||||||
|
|
||||||
public EntryContentsView(Context context):base(context, null) {
|
public EntryContentsView(Context context):base(context, null) {
|
||||||
inflate(context);
|
InflateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryContentsView(Context context, IAttributeSet attrs): base(context, attrs) {
|
public EntryContentsView(Context context, IAttributeSet attrs): base(context, attrs) {
|
||||||
|
|
||||||
inflate(context);
|
InflateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void inflate(Context context) {
|
private void InflateView() {
|
||||||
LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService);
|
LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService);
|
||||||
inflater.Inflate(Resource.Layout.entry_view_contents, this);
|
inflater.Inflate(Resource.Layout.entry_view_contents, this);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user