* added options to exclude libraries for faster build times (DEBUG only)

* implemented getFileEntry to get information about a single file
* password activity is launched automatically if there are recent files
This commit is contained in:
Philipp Crocoll 2013-09-28 21:14:21 +02:00
parent 74acd19092
commit a44e8a9680
23 changed files with 2001 additions and 4720 deletions

17
.gitignore vendored
View File

@ -138,3 +138,20 @@ Thumbs.db
/src/java/workspace/DBRoulette
/src/java/workspace/JavaFileStorageTest
/src/java/JavaFileStorage/src/keepass2android/javafilestorage/SecretKeys.java
/src/java/android-filechooser/code/bin
/src/java/android-filechooser/code/gen
/src/java/android-filechooser/code/project.zip
/src/java/android-filechooser/code/projectzip/bin
/src/java/android-filechooser/code/projectzip/res
/src/AndroidFileChooserBinding/bin/Debug
/src/AndroidFileChooserBinding/obj/Debug
/src/AppCompatV7Binding/bin/Debug
/src/AppCompatV7Binding/obj/Debug
/src/java/android-filechooser/code/AndroidUnusedResources1.6.2.jar
/src/java/android-filechooser/code/createProjectZip.bat
/src/java/android-filechooser/code/projectzip/project.zip
/src/java/android-filechooser/code/unused.txt

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<DefineConstants>DEBUG;EXCLUDE_KEYTRANSFORM</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
@ -155,7 +155,7 @@
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj">
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))">
<Project>{A57B3ACE-5634-469A-88C4-858BB409F356}</Project>
<Name>kp2akeytransform</Name>
</ProjectReference>

View File

@ -165,10 +165,14 @@ namespace KeePassLib.Native
try
{
#if !EXCLUDE_KEYTRANSFORM
Com.Keepassdroid.Crypto.Finalkey.NativeFinalKey key = new Com.Keepassdroid.Crypto.Finalkey.NativeFinalKey();
byte[] newKey = key.TransformMasterKey(pKey256, pBuf256, (int)uRounds);
Array.Copy(newKey, pBuf256, newKey.Length);
#else
return false;
#endif
}
catch(Exception e)
{

View File

@ -149,5 +149,11 @@ namespace keepass2android.Io
//TODO
throw new NotImplementedException();
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
//TODO
throw new NotImplementedException();
}
}
}

View File

@ -431,6 +431,11 @@ namespace keepass2android.Io
return _cachedStorage.ListContents(ioc);
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
return _cachedStorage.GetFileDescription(ioc);
}
public string GetBaseVersionHash(IOConnectionInfo ioc)
{

View File

@ -11,6 +11,7 @@ using Android.Runtime;
using Android.Views;
using Android.Widget;
using KeePassLib.Serialization;
#if !EXCLUDE_JAVAFILESTORAGE
using Keepass2android.Javafilestorage;
namespace keepass2android.Io
@ -27,4 +28,5 @@ namespace keepass2android.Io
get { return "dropbox"; }
}
}
}
}
#endif

View File

@ -73,5 +73,10 @@ namespace keepass2android.Io
{
throw new NotImplementedException();
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
}
}

View File

@ -106,6 +106,11 @@ namespace keepass2android.Io
/// Lists the contents of the given path
/// </summary>
IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc);
/// <summary>
/// returns the description of the given file
/// </summary>
FileDescription GetFileDescription(IOConnectionInfo ioc);
}
/// <summary>

View File

@ -5,12 +5,15 @@ using System.Linq;
using Android.App;
using KeePassLib.Serialization;
using KeePassLib.Utility;
#if !EXCLUDE_JAVAFILESTORAGE
using Keepass2android.Javafilestorage;
#endif
using Exception = System.Exception;
using FileNotFoundException = Java.IO.FileNotFoundException;
namespace keepass2android.Io
{
#if !EXCLUDE_JAVAFILESTORAGE
public abstract class JavaFileStorage: IFileStorage
{
public IEnumerable<string> SupportedProtocols { get { yield return Protocol; } }
@ -231,17 +234,7 @@ namespace keepass2android.Io
{
IList<JavaFileStorageFileEntry> entries = Jfs.ListFiles(IocToPath(ioc));
return entries.Select(
e => new FileDescription
{
CanRead = e.CanRead,
CanWrite = e.CanWrite,
IsDirectory = e.IsDirectory,
LastModified = JavaTimeToCSharp(e.LastModifiedTime),
Path = Protocol + "://" + e.Path,
SizeInBytes = e.SizeInBytes
}
);
return entries.Select(ConvertToFileDescription);
}
catch (FileNotFoundException e)
@ -254,6 +247,35 @@ namespace keepass2android.Io
}
}
private FileDescription ConvertToFileDescription(JavaFileStorageFileEntry e)
{
return new FileDescription
{
CanRead = e.CanRead,
CanWrite = e.CanWrite,
IsDirectory = e.IsDirectory,
LastModified = JavaTimeToCSharp(e.LastModifiedTime),
Path = Protocol + "://" + e.Path,
SizeInBytes = e.SizeInBytes
};
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
try
{
return ConvertToFileDescription(Jfs.GetFileEntry(IocToPath(ioc)));
}
catch (FileNotFoundException e)
{
throw new System.IO.FileNotFoundException(e.Message, e);
}
catch (Java.Lang.Exception e)
{
throw LogAndConvertJavaException(e);
}
}
private DateTime JavaTimeToCSharp(long javatime)
{
//todo test
@ -273,4 +295,5 @@ namespace keepass2android.Io
protected abstract string Protocol { get; }
}
#endif
}

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@ -93,7 +93,7 @@
<Compile Include="ProgressDialogStatusLogger.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_JAVAFILESTORAGE'))">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>
</ProjectReference>

View File

@ -116,5 +116,10 @@ namespace Kp2aUnitTests
{
throw new NotImplementedException();
}
public FileDescription GetFileDescription(IOConnectionInfo ioc)
{
throw new NotImplementedException();
}
}
}

View File

@ -284,13 +284,7 @@ public class DropboxFileStorage implements JavaFileStorage {
{
if (e.isDeleted)
continue;
FileEntry fileEntry = new FileEntry();
fileEntry.canRead = true;
fileEntry.canWrite = true;
fileEntry.isDirectory = e.isDir;
fileEntry.sizeInBytes = e.bytes;
fileEntry.path = e.path;
fileEntry.lastModifiedTime = com.dropbox.client2.RESTUtility.parseDate(e.modified).getTime();
FileEntry fileEntry = convertToFileEntry(e);
result.add(fileEntry);
}
return result;
@ -303,6 +297,17 @@ public class DropboxFileStorage implements JavaFileStorage {
}
private FileEntry convertToFileEntry(com.dropbox.client2.DropboxAPI.Entry e) {
FileEntry fileEntry = new FileEntry();
fileEntry.canRead = true;
fileEntry.canWrite = true;
fileEntry.isDirectory = e.isDir;
fileEntry.sizeInBytes = e.bytes;
fileEntry.path = e.path;
fileEntry.lastModifiedTime = com.dropbox.client2.RESTUtility.parseDate(e.modified).getTime();
return fileEntry;
}
@Override
public void delete(String path) throws Exception {
try
@ -315,4 +320,21 @@ public class DropboxFileStorage implements JavaFileStorage {
}
@Override
public FileEntry getFileEntry(String filename) throws Exception {
try
{
com.dropbox.client2.DropboxAPI.Entry dbEntry = mApi.metadata(filename, 0, null, false, null);
if (dbEntry.isDeleted)
throw new FileNotFoundException(filename+" is deleted!");
return convertToFileEntry(dbEntry);
} catch (DropboxException e) {
throw convertException(e);
}
}
}

View File

@ -84,6 +84,8 @@ public class FileEntry {
public List<FileEntry> listFiles(String dirName) throws Exception;
public FileEntry getFileEntry(String filename) throws Exception;
public void delete(String path) throws Exception;
}

View File

@ -453,14 +453,16 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
* parameters.
*/
private MatrixCursor doRetrieveFileInfo(Uri uri) {
Log.d(CLASSNAME, "retrieve file info");
Log.d(CLASSNAME, "retrieve file info "+uri.toString());
MatrixCursor matrixCursor = BaseFileProviderUtils.newBaseFileCursor();
String filename = extractFile(uri);
FileEntry f = getFileEntry(filename);
addFileInfo(matrixCursor, 0, f);
if (f == null)
addDeletedFileInfo(matrixCursor, filename);
else
addFileInfo(matrixCursor, 0, f);
return matrixCursor;
}// doRetrieveFileInfo()
@ -468,7 +470,26 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
/**
private void addDeletedFileInfo(MatrixCursor matrixCursor, String filename) {
int type = BaseFile.FILE_TYPE_NOT_EXISTED;
RowBuilder newRow = matrixCursor.newRow();
newRow.add(0);// _ID
newRow.add(BaseFile
.genContentIdUriBase(
getAuthority())
.buildUpon().appendPath(filename)
.build().toString());
newRow.add(filename);
newRow.add(getName(filename));
newRow.add(0);
newRow.add(0);
newRow.add(0);
newRow.add(type);
newRow.add(null);
newRow.add(FileUtils.getResIcon(type, getName(filename)));
}
/**
* Sorts {@code files}.
*
* @param taskId
@ -630,12 +651,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
protected FileEntry getFileEntry(String path) {
FileEntry f = new FileEntry();
f.path = path;
f.isDirectory = path.lastIndexOf(".") == -1;
return f;
}
protected abstract FileEntry getFileEntry(String path);
/**
* Lists all file inside {@code dirName}.

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/divider3"
android:text="Please note" />
android:text="@string/please_note" />
<TextView
android:id="@+id/disclaimer"
android:layout_width="fill_parent"
@ -92,7 +92,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/disclaimer"
android:text="Contributors" />
android:text="@string/contributors" />
<TextView
android:id="@+id/author"
android:layout_width="fill_parent"
@ -112,13 +112,19 @@
android:layout_height="wrap_content"
android:layout_below="@id/further_authors"
android:text="@string/credit_plugin1" />
<TextView
android:id="@+id/android_filechooser_contrib"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/plugin1"
android:text="@string/credit_android_filechooser" />
<TextView
android:id="@+id/Credit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/plugin1"
android:layout_below="@id/android_filechooser_contrib"
android:text="@string/CreditsText" />
</RelativeLayout>

View File

@ -188,6 +188,9 @@
<string name="author">Keepass2Android is developed by Philipp Crocoll.</string>
<string name="further_authors">Thanks to code contributions by %1$s.</string>
<string name="credit_plugin1">The Twofish Cipher Plugin for Keepass was developed by Scott Greenberg and is included in KP2A.</string>
<string name="credit_android_filechooser">android-filechooser was developed by Hai Bison</string>
<string name="please_note">Please note</string>
<string name="contributors">Contributors</string>
<string name="regular_expression">Regular expression</string>
<string name="TanExpiresOnUse_title">Tan expires on use</string>
<string name="TanExpiresOnUse_summary">Mark TAN entries expired when using them</string>

View File

@ -163,6 +163,7 @@ namespace keepass2android
public static string IntentToFilename(Intent data, Context ctx)
{
#if !EXCLUDE_FILECHOOSER
string EXTRA_RESULTS = "group.pals.android.lib.ui.filechooser.FileChooserActivity.results";
if (data.HasExtra(EXTRA_RESULTS))
{
@ -170,6 +171,7 @@ namespace keepass2android
Uri uri = (Uri) uris[0];
return Group.Pals.Android.Lib.UI.Filechooser.Providers.BaseFileProviderUtils.GetRealUri(ctx, uri).ToString();
}
#endif
String filename = data.Data.Path;
if (String.IsNullOrEmpty(filename))

View File

@ -28,7 +28,9 @@ using KeePassLib.Cryptography.Cipher;
using KeePassLib.Keys;
using KeePassLib.Serialization;
using Android.Preferences;
#if !EXCLUDE_TWOFISH
using TwofishCipher;
#endif
using keepass2android.Io;
namespace keepass2android
@ -386,7 +388,9 @@ namespace keepass2android
{
_fileStorages = new List<IFileStorage>
{
#if !EXCLUDE_JAVAFILESTORAGE
new DropboxFileStorage(Application.Context, this),
#endif
new BuiltInFileStorage()
};
}
@ -428,7 +432,9 @@ namespace keepass2android
GetResourceString(key);
}
#endif
#if !EXCLUDE_TWOFISH
CipherPool.GlobalPool.AddCipher(new TwofishCipherEngine());
#endif
}

View File

@ -2,11 +2,14 @@ using System;
using System.Collections.Generic;
using Android.Content;
using KeePassLib.Serialization;
#if !EXCLUDE_FILECHOOSER
using Keepass2android.Kp2afilechooser;
#endif
using keepass2android.Io;
namespace keepass2android
{
#if !EXCLUDE_FILECHOOSER
[ContentProvider(new[] { "keepass2android." + AppNames.PackagePart + ".kp2afilechooser.kp2afile" }, Exported = false)]
public class FileChooserFileProvider : Kp2aFileProvider
{
@ -59,7 +62,20 @@ namespace keepass2android
return false;
}
}
protected override FileEntry GetFileEntry(string filename)
{
try
{
return ConvertFileDescription(App.Kp2a.GetFileStorage(filename).GetFileDescription(ConvertPathToIoc(filename)));
}
catch (Exception e)
{
Kp2aLog.Log(e.ToString());
return null;
}
}
protected override void ListFiles(int taskId, string dirName, bool showHiddenFiles, int filterMode, int limit, string positiveRegex,
string negativeRegex, IList<FileEntry> fileList, bool[] hasMoreFiles)
@ -69,15 +85,7 @@ namespace keepass2android
var dirContents = App.Kp2a.GetFileStorage(dirName).ListContents(ConvertPathToIoc(dirName));
foreach (FileDescription e in dirContents)
{
fileList.Add(new FileEntry
{
CanRead = e.CanRead,
CanWrite = e.CanWrite,
IsDirectory = e.IsDirectory,
LastModifiedTime = CSharpTimeToJava(e.LastModified),
Path = e.Path,
SizeInBytes = e.SizeInBytes
}
fileList.Add(ConvertFileDescription(e)
);
}
}
@ -87,6 +95,19 @@ namespace keepass2android
}
}
private FileEntry ConvertFileDescription(FileDescription e)
{
return new FileEntry
{
CanRead = e.CanRead,
CanWrite = e.CanWrite,
IsDirectory = e.IsDirectory,
LastModifiedTime = CSharpTimeToJava(e.LastModified),
Path = e.Path,
SizeInBytes = e.SizeInBytes
};
}
private long CSharpTimeToJava(DateTime dateTime)
{
try
@ -101,4 +122,5 @@ namespace keepass2android
}
}
#endif
}

View File

@ -26,6 +26,7 @@ using Android.Widget;
using Android.Content.PM;
using KeePassLib.Serialization;
using keepass2android.Io;
using Environment = Android.OS.Environment;
namespace keepass2android
{
@ -481,9 +482,19 @@ namespace keepass2android
if (resultCode == KeePass.ExitFileStorageSelectionOk)
{
#if !EXCLUDE_FILECHOOSER
Intent i = Keepass2android.Kp2afilechooser.Kp2aFileChooserBridge.GetLaunchFileChooserIntent(this, FileChooserFileProvider.TheAuthority, data.GetStringExtra("protocolId")+":///");
StartActivityForResult(i, Intents.RequestCodeFileBrowseForOpen);
#else
Toast.MakeText(this, "TODO: make this more flexible.", ToastLength.Long).Show();
IOConnectionInfo ioc = new IOConnectionInfo
{
Path = Environment.ExternalStorageDirectory+"/keepass/keepass.kdbx"
};
LaunchPasswordActivityForIoc(ioc);
#endif
}
@ -569,6 +580,20 @@ namespace keepass2android
{
LaunchPasswordActivityForIoc(db.Ioc);
}
else
{
//if no database is loaded: load the most recent database
if (_DbHelper.HasRecentFiles())
{
Android.Database.ICursor filesCursor = _DbHelper.FetchAllFiles();
StartManagingCursor(filesCursor);
IOConnectionInfo ioc = _DbHelper.CursorToIoc(filesCursor);
if (App.Kp2a.GetFileStorage(ioc).RequiredSetup == null)
{
LaunchPasswordActivityForIoc(ioc);
}
}
}
}

View File

@ -24,7 +24,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
@ -253,7 +253,7 @@
<None Include="Resources\values-vi\strings.xml">
<Visible>False</Visible>
</None>
<None Include="..\java\kp2akeytransform\libs\mips\libfinal-key.so">
<None Include="..\java\kp2akeytransform\libs\mips\libfinal-key.so" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))">
<Link>libs\mips\libfinal-key.so</Link>
</None>
<None Include="Resources\drawable-hdpi\Thumbs.db">
@ -657,15 +657,15 @@
<Folder Include="SupportLib\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj">
<ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_FILECHOOSER'))">
<Project>{3c0f7fe5-639f-4422-a087-8b26cf862d1b}</Project>
<Name>AndroidFileChooserBinding</Name>
</ProjectReference>
<ProjectReference Include="..\AppCompatV7Binding\AppCompatV7Binding.csproj">
<ProjectReference Include="..\AppCompatV7Binding\AppCompatV7Binding.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_FILECHOOSER'))">
<Project>{23233a28-d74f-4bf8-b4d8-834060840bd7}</Project>
<Name>AppCompatV7Binding</Name>
</ProjectReference>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_JAVAFILESTORAGE'))">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>
</ProjectReference>
@ -677,15 +677,15 @@
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
<Name>Kp2aBusinessLogic</Name>
</ProjectReference>
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj">
<ProjectReference Include="..\kp2akeytransform\kp2akeytransform.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))">
<Project>{A57B3ACE-5634-469A-88C4-858BB409F356}</Project>
<Name>kp2akeytransform</Name>
</ProjectReference>
<ProjectReference Include="..\Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj">
<ProjectReference Include="..\Kp2aKeyboardBinding\Kp2aKeyboardBinding.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYBOARD'))">
<Project>{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}</Project>
<Name>Kp2aKeyboardBinding</Name>
</ProjectReference>
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj" Condition="!$(DefineConstants.Contains('EXCLUDE_TWOFISH'))">
<Project>{5cf675a5-9bee-4720-bed9-d5bf14a2ebf9}</Project>
<Name>TwofishCipher</Name>
</ProjectReference>
@ -700,11 +700,11 @@
</MonoDevelop>
</ProjectExtensions>
<ItemGroup>
<AndroidNativeLibrary Include="..\java\kp2akeytransform\libs\armeabi\libfinal-key.so">
<AndroidNativeLibrary Include="..\java\kp2akeytransform\libs\armeabi\libfinal-key.so" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))">
<Link>libs\armeabi\libfinal-key.so</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AndroidNativeLibrary>
<AndroidNativeLibrary Include="..\java\kp2akeytransform\libs\armeabi-v7a\libfinal-key.so">
<AndroidNativeLibrary Include="..\java\kp2akeytransform\libs\armeabi-v7a\libfinal-key.so" Condition="!$(DefineConstants.Contains('EXCLUDE_KEYTRANSFORM'))">
<Link>libs\armeabi-v7a\libfinal-key.so</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AndroidNativeLibrary>

View File

@ -242,6 +242,9 @@ namespace keepass2android
bool MakeAccessibleForKeyboard(PwEntry entry)
{
#if EXCLUDE_KEYBOARD
return false;
#else
bool hasData = false;
Keepass2android.Kbbridge.KeyboardDataBuilder kbdataBuilder = new Keepass2android.Kbbridge.KeyboardDataBuilder();
@ -288,7 +291,7 @@ namespace keepass2android
Keepass2android.Kbbridge.KeyboardData.EntryName = entry.Strings.ReadSafe(PwDefs.TitleField);
return hasData;
#endif
}
static string GetStringAndReplacePlaceholders(PwEntry entry, string key)
@ -314,8 +317,10 @@ namespace keepass2android
void clearKeyboard()
{
#if !EXCLUDE_KEYBOARD
Keepass2android.Kbbridge.KeyboardData.AvailableFields.Clear();
Keepass2android.Kbbridge.KeyboardData.EntryName = null;
#endif
}
private readonly Timer _timer = new Timer();